为什么我不能将Object类型的对象添加到List <! - ? - >中?

时间:2013-02-23 20:04:42

标签: java generics

据我所知,List<?>被定义为某个特定但未知类型的列表。因此,无论这个List的参数类型是什么,都应该扩展Object,因为在Java中,您不能拥有任何不扩展Object的类型。那么为什么下面的代码没有被编译?它是如何违反listObj

的不变量的
    List<?> listObj = returnSomeList();
    listObj.add(new Object()); //Why does this not work ?

5 个答案:

答案 0 :(得分:7)

List<?> listObj可以指向可以存储不同类型对象的任何类型的List。

您如何看待,如果例如

,让它添加任何对象是否安全
List<?> listObj = new ArrayList<String>();
listObj.add(new Object());

答案 1 :(得分:3)

List<?> and `List<? extends Object>` are identical.

你不能在使用的集合中添加任何东西吗?扩展类型语法(带子类型的通配符)。原因是您可能只是将错误的类型添加到集合中。

如果允许:

List<?> listOfObjects = new ArrayList<Object>();
listOfObjects.add(new Object()); //not valid
somewhere in future

listOfObjects = new ArrayList<Animal>();
listOfObjects.add(new Animal());

如果允许,您只需添加一个Animal into Object列表,这可以消除泛型类型的全部原因。当您从集合中检索动物时,您必须再次执行 instanceOf 检查,看看它是否是动物并将其转发回动物,就像我们在 pre-generics代码中所做的那样。

<强> Related Question

答案 2 :(得分:0)

因为Object是Java中最通用的类​​型。它不符合任何级别的特定要求。

答案 3 :(得分:0)

“?”被称为 WildCard Capture ,这意味着类型参数与未知类型匹配。这意味着

 List<?> listObj = returnSomeList(); 

的列表
 Unknown Type 

您尝试将对象添加到

列表中
  Unknown Type.

您发布的示例将为您提供编译时错误。

答案 4 :(得分:0)

您在List<Object>List<?>List<? extends Object>之间混淆。

使用List<Object>,您可以添加任何内容,但List<?>并不意味着这是一个列表,或者它(必然)会收到List<Object>

它可以收到List<Object>,在这种情况下,允许添加一个对象;但是,它还可以接收其他任何内容,例如List<Integer>List<String>List<Animal>。显然,您无法将对象添加到List<Integer>List<String>List<Animal>

由于编译器不记得指令之间对象的类型,即使将List<?>设置为List<Object>,添加对象也始终是非法的,因为编译器不会记住您已将其设置为List<Object>