List<? extends String> list = new Arraylist<String>();
list.add("foo");
给定一段代码给我编译时错误。我不明白为什么我不能在列表中添加字符串。 但代码意味着我们可以在列表中添加String类对象及其派生类对象 我仍然得到错误原因
答案 0 :(得分:2)
List<?>
。
例如,
public int getSize(List<?> itemList) {
return itemList.size();
}
它更像是Read Only
列表。
如果您打算制作String
项的新列表,则应使用以下内容。
List<String> list = new Arraylist<>();
list.add("foo");
或者,你可以使用它:
List<Object> list = new Arraylist<>();
list.add("foo");
答案 1 :(得分:1)
这将有效:
List<? super String> list = new ArrayList<String>();
list.add("foo");
然后你的编译器现在将调用者传递String
或超类型的对象列表。
当您说<? extends String>
时,它意味着它可以是任何扩展String
的类型。这意味着有人可以通过List
并接受它。
另见: Difference for <? super/extends String> in method and variable declaration
答案 2 :(得分:1)
基本上List<? extends String>
是未知类型的List,所有已知的是此类型扩展String。变量包含List<String>
。
现在String是final,所以没有子类......所以让我们考虑一下:
List<? extends A> list = new ArrayList<A>();
其中A
是一个带有子类B
的类。使用时,List<? extends A>
类型的变量可能是List<B>
的实例。我们无法向其添加A
,因为A
可能不是B
。
但你知道这是对的吗? 嗯,编译器没有,也没有预测未知类型和你实例化的逻辑连接,因为通常你可以在运行时更改该变量。
在乐观上命名为More Fun with Wildcards的教程中存在一个类似的示例,其中方法接受(Set<T>, T)
,并且使用(Set<?>, String)
通过Set<?>
变量进行非法调用包含Set<String>
的实例。尽管添加了extends
。