运行时已知的通用上限通配符实例化 [英] Generic upper bounded wildcard instantiation known at run time

查看:147
本文介绍了运行时已知的通用上限通配符实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

为什么我不能调用react方法
引用<的泛型?扩展Organic> 表示实例化Canb的泛型类型是Organic或Organic的子类型。

Why can't I call react method with Organic argument? The generic type ot the reference <? extends Organic> says that the generic type of the instantiation canb either a Organic, or a subtype of Organic.

是因为编译器没有直到运行时类型如此,才知道这种实例化泛型类型,它不会将任何值绑定到其泛型标准吗?

Is because the compiler doesn't know this instantiation generic type until runtime type an so, it does not bind any value to its generic criteria?

为什么这种情况有效?

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 并以实例化的通用类型的对象?扩展X 通配符,则您不能在对象上调用采用 T 类型参数的方法,因为编译器无法保证类型安全。但是,您可以调用返回 T 的方法(并将返回值分配给 X )。在您的特定示例中,看起来这应该是安全的

Quite simply, if you have an object of some generic type with a type parameter T instantiated with a ? extends X wildcard then you can't call methods on the object that take parameters of type T because the compiler can't guarantee type safety. However you can call methods that return T (and assign the return value to a variable of type X). In your specific example it looks like this should be safe

Organic<? extends Organic> compound = new Aliphatic<Organic>();
compound.react(new Organic());

但请记住,编译器必须匹配 react 基于声明类型(?扩展了有机)的调用,它不能依赖您在RHS上分配的内容。如果编译器允许这样做,那么还必须允许

but remember that the compiler has to match the react call based on the declaration type (? extends Organic), it can't rely on what you've assigned on the RHS. If the compiler allowed this then it would also have to allow

Organic<? extends Organic> compound = new Aliphatic<Hexane<?>>();
compound.react(new Organic());

这显然是不正确的-这与

which is clearly not correct - it's exactly the same situation as

Collection<? extends Number> nums = new ArrayList<Float>();
nums.add(Integer.valueOf(1));

(所有这些都是自 Organic 是通用的,您需要说 Organic<?><?>> 或类似的字词,而不仅仅是 Organic<?extended Organic>

(all this is aside from the fact that since Organic is generic you need to say Organic<? extends Organic<?>> or similar rather than just Organic<? extends Organic>)

这篇关于运行时已知的通用上限通配符实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆