在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 = new Arraylist<>(); list.add("foo"); 

这将有效:

 List list = new ArrayList(); list.add("foo"); 

然后你的编译器现在将调用者传递一个String或超类型的对象列表。

当你说 它意味着它可以是任何扩展String类型。 这意味着有人可以通过List ,它会接受它。

另见: <? 方法和变量声明中的super / extends String>

基本上List List是一个未知类型的List,所有已知的是此类型扩展String。 变量包含List的实例并不重要。

现在String是final,所以没有子类…所以让我们考虑一下:

 List list = new ArrayList(); 

其中A是一个带有子类B的类。 使用时, List类型的变量 List可能是List的实例。 我们不能添加A ,因为A可能不是B

但是你知道这是对的吗? 好吧,编译器没有 ,也没有预测未知类型和你实例化之间的逻辑连接,因为通常你可以在运行时更改该变量。

一个类似的例子存在于乐观上名为More Fun with Wildcards的教程中,其中一个方法接受(Set, T)并且使用(Set, String)前置非法调用(Set, String)尽管Set变量包含一个Set实例。 尽管增加了extends ,但问题在这里是一样的。