努力理解<;?扩展T>;Java中的通配符

努力理解<;?扩展T>;Java中的通配符,java,wildcard,extends,Java,Wildcard,Extends,我有一个非常基本的问题 下面的代码无法编译(假设Apple扩展了Fruit): List理解这一点的最佳方法是将通配符看作是对列表的说明,而不是对水果的说明。换言之: List<Banana> allBananas = getMyBananas(); enumerateMyFruit(allBananas); static void enumerateMyFruit(List<? extends Fruit> myFruit) { for (Fruit frui

我有一个非常基本的问题

下面的代码无法编译(假设Apple扩展了Fruit):


List理解这一点的最佳方法是将通配符看作是对列表的说明,而不是对水果的说明。换言之:

List<Banana> allBananas = getMyBananas();
enumerateMyFruit(allBananas);

static void enumerateMyFruit(List<? extends Fruit> myFruit) {
    for (Fruit fruit : myFruit)
        System.out.println(fruit);
}
列出所有香蕉=getMyBananas();
我的水果(所有香蕉);

果实的静态空隙(List首先请记住,对于没有通配符的泛型参数,您不能用一个替换另一个。如果一个方法采用
列表
,它就不会采用
列表
,它必须是精确匹配的。还要记住,这是关于变量的静态类型,与内容没有直接联系。即使您的
列表
c包含所有的苹果,你仍然不能用它代替
列表
。 所以我们讨论的是类型声明,而不是集合中的内容

还要记住,
instanceof
是在运行时完成的,泛型是在编译时工作的。泛型是帮助编译器找出事物的类型,这样你就不必求助于instanceof和casting


当一个方法foo接受一个泛型类型为
列表的参数时,它不应该是
new Apple()
(即括号缺失)?可能重复的
List<Banana> allBananas = getMyBananas();
enumerateMyFruit(allBananas);

static void enumerateMyFruit(List<? extends Fruit> myFruit) {
    for (Fruit fruit : myFruit)
        System.out.println(fruit);
}