ArrayList <t> vs ArrayList <! - ? - > </t>

时间:2011-07-21 17:32:52

标签: java generics

我知道ArrayList<T>的用途是什么,但我应该何时使用ArrayList<?>?你能用例子解释一下吗?感谢。

4 个答案:

答案 0 :(得分:13)

据我所知,ArrayList<?>基本上告诉编译器:

  

是的,我知道有一个通用版本的ArrayList可供我使用,但我真的,真的不知道我希望在这个中有什么样的对象。所以不要给我警告我没有像我应该那样使用泛型。

更新

我刚刚了解到使用原始类型(ArrayList)和通配符(通配符ArrayList<?>)之间存在真正的区别,这不仅仅是避免编译器警告。显然,一旦你将某些东西声明为Raw类型,任何泛型都不会对该类型的任何方法起作用,即使泛型不是基于你省略的类型。 See here for an example

因此,尽管我的原始答案通常是正确的,但我认为使用ArrayList<?>代替ArrayList并不仅仅是删除编译器警告的问题非常重要。

答案 1 :(得分:5)

ArrayList<?>表示一个未知对象的集合,也就是说,它可以是任何东西。可以从中读取,但你不能写它。

听起来像是这样的:

  

我是收藏品!我可以读未知,但由于我不知道它的类型,我不能添加东西

请参阅Oracle非常有用的tutorial

另外,我发现MIT Software Construction类中的这些slides非常有用,而且这个泛型tutorial

答案 2 :(得分:5)

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

  

注意:也可以使用super指定下限   关键字而不是扩展。因此,代码<? super Animal>,   会被解读为“未知类型的动物,超级动物,   可能是Animal本身“。您也可以使用。指定未知类型   无界通配符,看起来像<?>。一个无界的通配符   基本上与说<? extends Object>

相同

答案 3 :(得分:0)

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

class Base {}

然后上课Extender extends Base{}

现在,如果您有Collection<Extender> collection并且想要使用此方法调用它。

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

以上不起作用或不起作用。什么会有效

doSomething(Collection<? extends Base> c)

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

相同