ArrayList<T>与ArrayList<?>区别

11

我知道 ArrayList<T> 用于什么,但何时应该使用 ArrayList<?>?你能举例说明吗?谢谢。


实际上,“<?>”几乎从不单独使用。通配符与“extends”和“super”一起使用时非常有用。 - trutheality
2
如果我没记错的话,ArrayList<?> 只是 ArrayList<? extends Object> 的简写。因此,在某种意义上,<?> 永远不会单独使用。 - emory
我试图给你一个例子,应该能帮助你理解。如果你还有更多的问题,请让我知道。 - Amir Raminfar
4个回答

14
据我了解,ArrayList<?>基本上告诉编译器:

是的,我知道有一个泛型版本的ArrayList可供使用,但是我真的不知道这个ArrayList中会有什么类型的对象。所以不要警告我没有正确地使用泛型。

更新

我刚刚了解到使用原始类型(ArrayList)和带通配符的泛型(ArrayList<?>)之间确实存在着真正的区别,这不仅仅是为了避免编译器警告。显然,一旦将某个东西声明为原始类型,任何方法都无法在该类型上使用泛型,即使泛型并不是基于您省略的类型。 点击此处查看示例

因此,尽管我的最初答案大体上是正确的,但我认为提到使用 ArrayList<?>而不是 ArrayList 更重要的是,这不仅仅是消除编译器警告的问题。


3
原文:There are more differences between raw types and types with wildcard parameters. For example, you can add objects to a raw ArrayList, but not to an ArrayList<?>翻译:原始类型和带有通配符参数的类型之间存在更多差异。例如,您可以向原始ArrayList添加对象,但无法向 ArrayList<?> 添加。 - newacct
@newacct:我不认为那是正确的。虽然我现在没有可用的Java环境,但是将对象添加到“ArrayList <?>”似乎在Groovy控制台上完全正常:http://groovyconsole.appspot.com/script/550003 - StriplingWarrior
2
这在Java中不应该起作用(producer extends,consumer super)。此外,在Java中甚至不能使用new ArrayList <?>(),所以也许Groovy有点不同。 - newacct
@newacct:我有机会使用Java环境玩耍了一下,看起来你两方面都是正确的。非常好的观察。 - StriplingWarrior

5
ArrayList<?> 表示一个未知对象的集合,也就是说它可以是任何东西。可以从中读取数据,但无法向其中添加数据。以下是类似的表述:

我是一个集合!我能读取未知的内容,但由于我不知道它的类型,所以无法添加内容。

可以参考 Oracle 提供的非常有用的 教程 以及 MIT 软件构建课程的这些幻灯片和这个泛型教程

那么,这是一种聪明的方法,在编译时创建一个只读列表吗?但话说回来,它有什么用处呢?因为你无法将任何数据放入其中! - Christian Bongiorno

5

http://download.oracle.com/javase/tutorial/java/generics/wildcards.html

注意:使用 super 关键字可以指定下限。因此,<? super Animal> 代码将被解读为“未知类型是 Animal 的超类型,可能是 Animal 本身”。你也可以用无界通配符指定未知类型,它看起来像 <?>。无界通配符基本上等同于 <? extends Object>


0

这里有一个具体的例子。假设你有一个

class Base {}

现在有一个类 Extender 继承自 Base

如果你有一个 Collection<Extender> collection 并且想要使用这个方法调用它。

public void doSomething(Collection<Base> c){...} 

以上方法将无法工作或编译。可行的方法是:

doSomething(Collection<? extends Base> c)

这基本上是说我不关心 ? 的类型,但它必须扩展 Base。现在你明白了,它会帮助你理解 ? 的含义。它与使用 <? extends Object> 相同。


因此,如果您放置 Collection<? super Base> c,那么它意味着只有 Base 的超类(包括 Base 本身)被接受?寻求确认。 - Christian Bongiorno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接