2

据我了解, a List<?>被定义为一些特定但未知类型的列表。所以无论 this 的参数类型是什么List,它都应该是扩展的,Object因为在 Java 中你不能有任何不扩展的类型Object。那么为什么下面的代码没有被编译呢?它是如何违反不变量的listObj

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

5 回答 5

7

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

您如何看待,例如,让它添加任何对象是否安全

List<?> listObj = new ArrayList<String>();
listObj.add(new Object());
于 2013-02-23T20:09:52.660 回答
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 添加到 Object 列表中,这会破坏泛型类型的全部原因。当您从集合中检索 Animal 时,您必须再次执行instanceOf检查以查看它是否是 Animal 并将其转换回 Animal,就像我们在前泛型代码中所做的那样。

相关问题

于 2013-02-23T20:07:25.557 回答
0

您正在混淆 aList<Object>和 a List<?>or List<? extends Object>

使用 a List<Object>,您可以将任何内容放入其中,但这List<?>并不意味着这是一个 List 或它将(必然)收到 a List<Object>

它可以接收一个List<Object>,在这种情况下添加一个 Object 是允许的;但是,它也可以接收任何其他内容,例如 a List<Integer>、 aList<String>或 a List<Animal>。显然,您不能将 Object 添加到 a List<Integer>、 aList<String>或 a List<Animal>

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

于 2013-02-23T20:33:57.797 回答
0

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

 List<?> listObj = returnSomeList(); 

是一个列表

 Unknown Type 

并且您正在尝试将对象添加到列表中

  Unknown Type.

您发布的示例会给您编译时错误。

于 2013-02-23T20:18:05.620 回答
0

因为Object是 Java 中最通用的类​​型。它没有资格被称为特定于任何级别。

于 2013-02-23T20:09:46.500 回答