据我所知,List<?>
被定义为某个特定但未知类型的列表。因此,无论这个List
的参数类型是什么,都应该扩展Object
,因为在Java中,您不能拥有任何不扩展Object
的类型。那么为什么下面的代码没有被编译?它是如何违反listObj
List<?> listObj = returnSomeList();
listObj.add(new Object()); //Why does this not work ?
答案 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>
。