在运行时已知的通用上限有界通配符实例化

时间:2012-10-15 14:54:11

标签: java generics wildcard bounded-wildcard

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();
    }
}

1 个答案:

答案 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<?>>