Java泛型类型擦除

Iza*_*rek 11 java generics erasure

我想问一下java类型的擦除规则.

如果我们有课程:

public class Shape{}
public class Circle extends Shape{}


public class Base<T extends Shape>{
    T x;
    public void setX(T t){}
}

public class MainClass(){
    public static void main(String... _arg){
         Base<? extends Shape> bs = new Base<Circle>(); 
         bs.setX(new Circle()); // <- compilation problem
    }
}
Run Code Online (Sandbox Code Playgroud)

你能解释一下为什么调用setX()方法会导致编译问题吗?

Oli*_*rth 21

因为编译器不知道它new Circle是有效的.考虑以下代码:

Base<? extends Shape> bs = new Base<Square>();  // Really a Base<Square> 
bs.setX(new Circle());
Run Code Online (Sandbox Code Playgroud)

(仅供参考,在通配符Java教程中给出了一个非常相似的例子.)

您现在可以惊叹"但编译器可以看到它真的是一个Base<Square>!".但不是一般的.考虑一下:

Base<? extends Shape> bs = someInterface.getBaseOfSomeKindOfShape();
bs.setX(new Circle());
Run Code Online (Sandbox Code Playgroud)

  • +1或`(Math.random()> .5)?new Base <Square>():new Base <Circle>()`.编译器无法想出那一个. (6认同)