MyClass e = new MyClass();
List<Object> ok = new ArrayList<Object>();
List<? extends Object> ko = new ArrayList<Object>();
ok.add(e);
ko.add(e); // doesn't compile
为什么不编译? MyClass
是Object
...
有关信息,我收到以下消息:
The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the arguments (MyClass)
答案 0 :(得分:7)
这是你的问题:
List<? extends Object>
这意味着“它是某个类型T的列表,它扩展了Object,但我不关心T是什么”。
所以这是有效的:
List<? extends Object> ko = new ArrayList<Banana>();
...但你不想要:
ko.add(e);
在那时编译,不是吗?因为MyClass
不是Banana
。
请参阅Java generics FAQ了解更多的更多信息。
答案 1 :(得分:1)
extends
,Consumer = super
。
由于您使用ko
作为使用者(您向其添加了一个对象),因此您应声明为:
List<? super Object> ko = new ArrayList<Object>();
或许可以更好地说明这个概念:
List<? super MyClass> ko = new ArrayList<Object>();
您可能会想到它只能将MyClass对象分配给类型为MyClass的变量或任何超类型 - 您只能将MyClass对象添加到类型为MyClass的List中,或者任何超级类型。
回到你的例子,List<? extends Object> ko
不能成为正确的类型声明,因为它也会接受这个:
List<? extends Object> ko = new ArrayList<String>();
您在此处看到,基于ko
的泛型类型,编译器无法确定实际列表是否接受MyClass的实例。