带有通配符的列表会导致通用伏都教错误 [英] Lists with wildcards cause Generic voodoo error

查看:30
本文介绍了带有通配符的列表会导致通用伏都教错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道为什么下面的代码不能编译?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);

推荐答案

(这里假设 BarBaz 都是 Foo 的子类型>.)

(I assume here that Bar and Baz are both subtypes of Foo.)

列表 表示某种类型的元素列表,它是 Foo 的子类型,但我们不知道是哪种类型.此类列表的示例包括 ArrayListLinkedListArrayList.

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 对象放入其中,BarBaz> 对象.但是我们仍然知道类型参数是 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 对象的对象 - 以及 BarBazFoo 的子类型,所有的 BarBaz 对象都是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆