【问题标题】:Type of a generic method parameter泛型方法参数的类型
【发布时间】:2021-02-11 10:02:14
【问题描述】:

假设我有一个带有泛型参数的方法:

public <U> void genericMethod(U param) {
    // doStuff
}

我也有两个类,其中一个扩展了另一个:

public class A {}
public class B extends A {}

我这样做:

A var = new B();
genericMethod(var);

genericMethod中,U的类型是什么?

我传递的变量genericMethod被声明为A,但实际上是BU的类型也是AB

我已尝试对其进行测试,但找不到在运行时获取 U 信息的方法。

【问题讨论】:

  • “什么是类型”到底是什么意思。 var 是对 B 类型对象的引用。
  • “但我找不到在运行时获取 U 信息的方法”,因为在运行时没有关于 U 的任何信息。泛型纯粹是编译时间问题。现在知道了,你应该知道问题的答案了。

标签: java generics inheritance


【解决方案1】:

让我们稍微修改一下您的示例:

public class Example {
    static class A {
        int x;
    }
    static class B extends A {}

    static <U> U genericMethod(U param) {
        int i = param.x; // compile time error
        System.out.println(param.getClass()); // prints B
        return param;
    }

    public static void main(String... args) {
        A var1 = new B();
        A var2 = genericMethod(var1);
        B var3 = genericMethod(var1); // compile time error
    }
}

从您调用genericMethod 的角度来看,U 属于A 类型,因此我们可以将返回值分配给A,但不能分配给B。

genericMethod的实现来看,U的类型是Object,因为我们没有给它设置任何界限,所以我们不能例如引用一个成员字段A. 如果我们写static &lt;U extends A&gt; U genericMethod(U param),那么 U 的类型就是 A。

param的实际运行时类型是B,如果你调用getClass()就可以看到

【讨论】:

  • 我认为这个答案可以更好地解释 1) 引用变量的编译时类型 2) 引用变量的运行时类型 3) 参数对象的运行时类型.
  • “从genericMethod的实现来看,U是Object类型” 这里指的是参数变量的运行时类型,但没有明确说。在编译期间,参数的类型只是UgenericMethod。这可以清楚地观察到,因为您不能将 Object 类型的值分配给 param
  • 另外,Java 中的变量不适合使用名称varvar 在 Java 10 及更高版本中具有特殊含义!该代码仍然合法,但相当混乱!
【解决方案2】:

泛型类型在编译器时解析。所以&lt;U&gt;是由var的编译时类型决定的,即A

【讨论】:

  • 谢谢,我就是这么想的,但不确定。
【解决方案3】:

U 的类型为 Object,因为您可以将 anything 传递给 genericMethod。
它可以是字符串、整数、A 或 B 或其他任何东西。所有对象中最常见的分母是Object,所以在 genericMethod 内部,param 的类型将是 Object。


如果你需要U是A或者B,可以定义为

public <U extends A> void genericMethod(U param) {

但唯一的保证是它(至少)是 A,因此您可以访问 A 的属性和方法,但不能访问 B(尽管 B 可以覆盖 A 的属性)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多