据我了解, a List<?>
被定义为一些特定但未知类型的列表。所以无论 this 的参数类型是什么List
,它都应该是扩展的,Object
因为在 Java 中你不能有任何不扩展的类型Object
。那么为什么下面的代码没有被编译呢?它是如何违反不变量的listObj
List<?> listObj = returnSomeList();
listObj.add(new Object()); //Why does this not work ?
List<?> listObj
可以指向可以存储不同类型对象的任何类型的 List。
您如何看待,例如,让它添加任何对象是否安全
List<?> listObj = new ArrayList<String>();
listObj.add(new Object());
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,就像我们在前泛型代码中所做的那样。
您正在混淆 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>
。
“?” 称为WildCard Capture,这意味着类型参数与未知类型匹配。这表示
List<?> listObj = returnSomeList();
是一个列表
Unknown Type
并且您正在尝试将对象添加到列表中
Unknown Type.
您发布的示例会给您编译时错误。
因为Object
是 Java 中最通用的类型。它没有资格被称为特定于任何级别。