在List中使用通配符时编译时错误
List list = new Arraylist(); list.add("foo");
给定一段代码给我编译时错误。我不明白为什么我不能在列表中添加字符串。 但是代码意味着我们可以在列表中添加String类对象和它的派生类对象,但我仍然得到错误原因
List>
只应在您不关心项目的数据类型并且对获取列表大小等操作感兴趣时使用。
例如,
public int getSize(List> itemList) { return itemList.size(); }
它更像是一个Read Only
列表。
如果您打算创建一个新的String
项列表,则应该使用以下内容。
List list = new Arraylist<>(); list.add("foo");
或者,您可以使用此:
List
这将有效:
List super String> list = new ArrayList(); list.add("foo");
然后你的编译器现在将调用者传递一个String
或超类型的对象列表。
当你说 extends String>
extends String>
它意味着它可以是任何扩展String
类型。 这意味着有人可以通过List
,它会接受它。
另见: <? 方法和变量声明中的super / extends String>
基本上List extends String>
List extends String>
是一个未知类型的List,所有已知的是此类型扩展String。 变量包含List
的实例并不重要。
现在String是final,所以没有子类…所以让我们考虑一下:
List extends A> list = new ArrayList();
其中A
是一个带有子类B
的类。 使用时, List extends A>
类型的变量 List extends A>
可能是List
的实例。 我们不能添加A
,因为A
可能不是B
但是你知道这是对的吗? 好吧,编译器没有 ,也没有预测未知类型和你实例化之间的逻辑连接,因为通常你可以在运行时更改该变量。
一个类似的例子存在于乐观上名为More Fun with Wildcards的教程中,其中一个方法接受(Set
并且使用(Set>, String)
前置非法调用(Set>, String)
尽管Set>
变量包含一个Set
实例。 尽管增加了extends
,但问题在这里是一样的。