简体   繁体   English

名单 <? extends Object> #add(new MyClass())无法编译

[英]List<? extends Object>#add(new MyClass()) doesn't compile

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

Why does it doesn't compile? 为什么不编译? MyClass is whatever a subclass of Object ... MyClassObject的子类......

For information, I get the following message: 有关信息,我收到以下消息:

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

This is your problem: 这是你的问题:

List<? extends Object>

That means "it's a list of some type T which extends Object, but I don't care what T is". 这意味着“它是一个扩展Object的类型T的列表,但我不关心T是什么”。

So this would be valid: 所以这是有效的:

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

... but you wouldn't want: ......但你不想要:

ko.add(e);

to compile at that point, would you? 在那时编译,不是吗? Because a MyClass isn't a Banana . 因为MyClass不是Banana

See the Java generics FAQ for much more information. Java泛型常见问题解答更多信息。

Josh Block, in Effective Java , teaches us PECS : Producer = extends , Consumer = super . 有效Java中的 Josh Block教我们PECS :Producer = extends ,Consumer = super

Since you are using ko as a consumer (you add an object to it) you should declare is as: 由于你使用ko作为消费者 (你向它添加一个对象),你应该声明为:

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

Perhaps a better illustration of the concept would be: 或许更好地说明这个概念:

List<? super MyClass> ko = new ArrayList<Object>();

You may think of it in the same way that you can only assign a MyClass object to a variable whose type is MyClass, or any super type -- you can only add a MyClass object to a List whose type is MyClass, or any super type. 您可能会想到它的方式与只能将MyClass对象分配给类型为MyClass的变量或任何超类型 - 您只能将MyClass对象添加到类型为MyClass的List或任何超类型。

Going back to your example, List<? extends Object> ko 回到你的例子, List<? extends Object> ko List<? extends Object> ko can't be the right type declaration because it would also accept this: List<? extends Object> ko不能是正确的类型声明,因为它也接受这个:

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

And you see here that, based on the generic type of ko , the compiler cannot be sure that the actual List accepts instances of MyClass. 你在这里看到,基于ko的泛型类型,编译器无法确定实际的 List是否接受MyClass的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM