[英]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
... MyClass
是Object
的子类......
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.