仅指定某些类型参数的泛型派生类的引用会导致编译器出现“不兼容类型”错误

时间:2014-01-20 15:09:11

标签: java generics

为什么编译器会报告以下代码的错误?

class B<T, U> {
  T t; U u;
  public B(T t, U u) { this.t = t; this.u = u; }
  public T getT() { return t; }
  public U getU() { return u; }
}
class D<T> extends B<T, String> {
  public D(T t, String u) {
    super(t, u);
  }
}

public static void main(String[] args) {
  D<Integer> d1 = new D<Integer>(1, "1");
  String s1 = d1.getU();  // This line compiles
  D d2 = new D<Integer>(1, "1");
  String s2 = d2.getU();  // This line makes the compiler complain that getU returns Object and s2 is String
}

为什么最后一行不起作用?我知道getT()是否不起作用,因为在s2的类型中没有指定该类型参数。但是getU将总是返回一个String ...

1 个答案:

答案 0 :(得分:3)

使用泛型时,方法参数,返回类型和泛型类型都是从引用的编译时类型的方法调用中解析或推断出来的。

当你有

D<Integer> d1 = new D<Integer>(1, "1");
String s1 = d1.getU();  // This line compiles

编译器知道d1的类型为D<Integer>。它还从其超类型中解析了d1.getU()String的返回类型。

但是,使用raw types

  

原始类型的超类(分别是超级接口)是   任何超类(超级接口)的擦除   参数化调用。

所以getU()显示为

public Object getU()

使用原始类型D的引用时。