2
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

为什么它不编译?MyClassObject...的子类

有关信息,我收到以下消息:

The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the arguments (MyClass)
4

2 回答 2

7

这是你的问题:

List<? extends Object>

这意味着“它是扩展 Object 的某种类型 T 的列表,但我不在乎 T 是什么”。

所以这将是有效的:

List<? extends Object> ko = new ArrayList<Banana>();

...但你不会想要:

ko.add(e);

在那个时候编译,你会吗?因为 aMyClass不是Banana.

有关更多信息,请参阅Java 泛型常见问题解答。

于 2012-12-11T17:11:50.897 回答
1

Josh Block 在Effective Java中教给我们PECS:生产者 = extends,消费者 = 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,编译器无法确定实际的List 是否接受 MyClass 的实例。

于 2012-12-11T18:30:06.537 回答