class Aliphatic<F> extends Organic<F>{}
class Hexane<G> extends Aliphatic<G>{}
public class Organic<E>{
void react(E e){}
static void main(String[] args){
Organic<? extends Organic> compound = new Aliphatic<Organic>();
compound.react(new Organic());
}
}
为什么我不能使用Organic参数调用react方法?
参考<? extends Organic>
的泛型类型表示实例化的泛型类型可以是有机的,也可以是有机的子类型。
是因为编译器在运行时输入类型之前不知道这个实例化泛型类型,它不会将任何值绑定到它的通用标准吗?
为什么这个案子有效?这种情况是否相同?
public class WildcardCollection {
public static void main (String[] args){
WildcardCollection w = new WildcardCollection();
w.myMethod(new Items("hola",1)); //Compile
w.myMethod(new SubItems("nuevo",3)); //Compile
}
public <T extends Items> void myMethod(T a){ //Same as above
System.out.println("hi: "+a);
}
}
class SubItems extends Items {
SubItems(){};
SubItems(String s, int i){ super(s,i);}
}
class Items implements Comparable<Items> {
private String name;
private int value;
public Items() {}
public Items(String n, int i){ this.name = n; this.value = i;}
public String getName(){ return this.name;}
public int getValue(){ return this.value;}
public String toString(){ return "(" + this.name + "-" + this.value + ")";}
public int compareTo(Items i){
return this.value - i.getValue();
}
}
答案 0 :(得分:2)
很简单,如果你有一个泛型类型的对象,类型参数T
用? extends X
通配符实例化,那么你就不能调用带有{{1}参数类型的对象的方法。 1}}因为编译器不能保证类型安全。但是,您可以调用返回T
的方法(并将返回值分配给类型为T
的变量)。在您的具体示例中,它看起来应该是安全的
X
但请记住,编译器必须根据声明类型(Organic<? extends Organic> compound = new Aliphatic<Organic>();
compound.react(new Organic());
)匹配react
调用,它不能依赖于您在RHS。如果编译器允许这样做,那么它也必须允许
? extends Organic
显然不正确 - 这与
的情况完全相同Organic<? extends Organic> compound = new Aliphatic<Hexane<?>>();
compound.react(new Organic());
(所有这些都不是因为Collection<? extends Number> nums = new ArrayList<Float>();
nums.add(Integer.valueOf(1));
是通用的,你需要说Organic
或类似而不只是Organic<? extends Organic<?>>
)