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>
的泛型类型表示实例化的泛型类型可以是Organic或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();
}
}
最佳答案
简而言之,如果您的某个通用类型的对象的类型参数T
用通配符? extends X
实例化,则您无法在该对象上调用采用参数T
的方法,因为编译器无法保证类型安全。但是,您可以调用返回T
的方法(并将返回值分配给X
类型的变量)。在您的特定示例中,这看起来应该很安全
Organic<? extends Organic> compound = new Aliphatic<Organic>();
compound.react(new Organic());
但是请记住,编译器必须根据声明类型(
react
)匹配? extends Organic
调用,它不能依赖您在RHS上分配的内容。如果编译器允许这样做,那么它也必须允许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<?>>
或类似的字词,而不仅仅是Organic<? extends Organic>
)关于java - 运行时已知的通用上限通配符实例化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12898264/