2013-07-24 54 views
25

所以我一直在寻找了一些Java代码和偶然发现:用什么说<?扩展SomeObject>而不是<SomeObject>

List<? extends SomeObject> l; 

基本上这个名单接受的某种SomeObject的所有对象 - SomeObject本身或其继承者。但根据多态,它的继承者,也可作为作用似乎SomeObject,所以这会工作,以及:

List<SomeObject> l; 

那么,为什么会有人使用第一个选项,当二是明确界定,实际上是相同的?

+7

这是在Java教程很好解释的基本原则是:http://docs.oracle.com /javase/tutorial/extra/generics/wildcards.html –

回答

27
List<SomeObject> l; 

在此,你不能说List<SomeObject> l = new ArrayList<SubClassOfSomeObjectClass>;不允许) 哪来的

List<? extends SomeObject> l; 

你可以说

List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>;允许

但需要注意的是,在List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>;不能给你的列表L因为添加任何东西?代表未知等级(除当然空)。

更新:对于在评论你的问题What could I possibly do with a list if I cannot add anything to it?

现在考虑,你必须写一个函数来打印你的列表,但心目中的情况下,你必须只接受具有:有子类对象名单您的SomeObject。在这种情况下,我上面说你不能使用

public void printList(List<SubClassOfSomeObjectClass> someList)

那么你会怎么办?你会做这样的事情

public void printList(List<? extends SomeObject> someList) { 
     for(SomeObject myObj : someList) { 
      //process read operations on myObj 
     } 
+1

请你澄清两件事: 如果我不能添加任何东西,我可以怎样做一个列表 在构造函数中声明的类的含义< > –

+0

请参考以下两个链接(通配符:非常精美的解释)http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html和http://docs.oracle.com/javase/tutorial/ extra/generics/wildcards.html –

+0

@OrCy ngiser'如果我不能添加任何东西,我可以用列表做些什么?'有时你只想读取/使用某个容器的内容而不修改它。 '在<>里的构造函数中声明的Class的含义是什么?''不知道你在问什么。简单地说它是通用类型。更多信息[here](http://docs.oracle.com/javase/tutorial/java/generics/)。如果您询问'<>'看看[这里](http://stackoverflow.com/q/4166966/1393766)和[这里](http://docs.oracle.com/javase/7/ docs/technotes/guides/language/type-in​​ference-generic-instance-creation.html) – Pshemo

2

List<? extends SomeObject> l;不接受new SomeObject() 但是List<SomeObject> l;

什么也没有工作: List<SomeObject> l = new ArrayList<SubTypeOfSomeObject>()

什么是工作: List<? extends SomeObject> l = new ArrayList<SubTypeOfSomeObject>()

-2

作为第一个答案,

List<? extends SomeObject> l; 

必须包含的对象,从SomeObject继承,而不是一些直接SomeObject。

+10

这是错误的,该列表也可以包含一个SomeObject。 – assylias

4

您要阅读的关键链接是http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html,详细解释了通用通配符。

List<SomeObject>List<? extends SomeObject>不一样。遵守以下

List<Object> x = new ArrayList<Object>(); 
List<String> y = new ArrayList<String>(); 
// x = y; Will throw Compilation exception 
List<? extends Object> z = y; //will pass compilation 

您可能需要观察,您可以添加说一个String于x和y列表但它会在你写的说的库函数(如本例中的printCollection有用显示在链接中),而不是接受Collection<Object>,在这种情况下,用户无法将他必须使用的字符串列表传递给您的方法,如果您接受Collection<? extends Object>,则用户可以通过他的Collection<Apple>, Collection<Orange>等等,而不必明确创建另一个列表。

0

X不能被添加到List<Y>即使X可以转换为Y

所以,在你的第二个情况下,如果List<X> l;被允许添加X的子类,这会破坏类型安全

相关问题