带有通配符的列表会导致通用伏都教错误 [英] Lists with wildcards cause Generic voodoo error
问题描述
有谁知道为什么下面的代码不能编译?add() 和 addAll() 都没有按预期工作.删除?扩展"部分使一切正常,但是我将无法添加 Foo 的子类.
Does anyone know why the following code does not compile? Neither add() nor addAll() works as expected. Removing the "? extends" part makes everything work, but then I would not be able to add subclasses of Foo.
List<? extends Foo> list1 = new ArrayList<Foo>();
List<? extends Foo> list2 = new ArrayList<Foo>();
/* Won't compile */
list2.add( new Foo() ); //error 1
list1.addAll(list2); //error 2
错误 1:
IntelliJ 说:
IntelliJ says:
add(capture<? extends Foo>) in List cannot be applied to add(Foo)
编译器说:
cannot find symbol
symbol : method addAll(java.util.List<capture#692 of ? extends Foo>)
location: interface java.util.List<capture#128 of ? extends Foo>
错误 2:
IntelliJ 给了我
IntelliJ gives me
addAll(java.util.Collection<? extends capture<? extends Foo>>) in List cannot be applied to addAll(java.util.List<capture<? extends Foo>>)
而编译器只是说
cannot find symbol
symbol : method addAll(java.util.List<capture#692 of ? extends Foo>)
location: interface java.util.List<capture#128 of ? extends Foo>
list1.addAll(list2);
推荐答案
(这里假设 Bar
和 Baz
都是 Foo
的子类型>.)
(I assume here that Bar
and Baz
are both subtypes of Foo
.)
列表
表示某种类型的元素列表,它是 Foo 的子类型,但我们不知道是哪种类型.此类列表的示例包括 ArrayList
、LinkedList
和 ArrayList
.
List<? extends Foo>
means a list of elements of some type, which is a subtype of Foo, but we don't know which type. Examples of such lists would be a ArrayList<Foo>
, a LinkedList<Bar>
and a ArrayList<Baz>
.
由于我们不知道哪个子类型是类型参数,所以我们不能将 Foo
对象放入其中,Bar
或 Baz
> 对象.但是我们仍然知道类型参数是 Foo
的子类型,因此列表中的每个元素(以及我们可以从列表中获取的)都必须是一个 Foo
对象,所以我们可以使用 Foo f = list.get(0);
和类似的东西.
As we don't know which subtype is the type parameter, we can't put Foo
objects into it, neither Bar
or Baz
objects. But we still know that the type parameter is a subtype of Foo
, so every element already in the list (and which we can get from the list) must be a Foo
object, so we can use Foo f = list.get(0);
and similar things.
这样的列表只能用于从列表中取出元素,根本不能添加元素(除了null
,但我不知道编译器是否真的允许这样做).
Such a list can only be used for taking elements out of the list, not to adding elements at all (apart from null
, but I don't know if the compiler actually allows this).
A List
另一方面允许添加任何是 Foo
对象的对象 - 以及 Bar
和 Baz
是 Foo
的子类型,所有的 Bar
和 Baz
对象都是 Foo
对象,所以它们可以也添加.
A List<Foo>
on the other hand allows adding any object which is a Foo
object - and as Bar
and Baz
are subtypes of Foo
, all Bar
and Baz
objects are Foo
objects, so they can be added, too.
这篇关于带有通配符的列表会导致通用伏都教错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!