所以我一直在寻找了一些Java代码和偶然发现:用什么说<?扩展SomeObject>而不是<SomeObject>
List<? extends SomeObject> l;
基本上这个名单接受的某种SomeObject的所有对象 - SomeObject本身或其继承者。但根据多态,它的继承者,也可作为作用似乎SomeObject,所以这会工作,以及:
List<SomeObject> l;
那么,为什么会有人使用第一个选项,当二是明确界定,实际上是相同的?
所以我一直在寻找了一些Java代码和偶然发现:用什么说<?扩展SomeObject>而不是<SomeObject>
List<? extends SomeObject> l;
基本上这个名单接受的某种SomeObject的所有对象 - SomeObject本身或其继承者。但根据多态,它的继承者,也可作为作用似乎SomeObject,所以这会工作,以及:
List<SomeObject> l;
那么,为什么会有人使用第一个选项,当二是明确界定,实际上是相同的?
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
}
请你澄清两件事: 如果我不能添加任何东西,我可以怎样做一个列表 在构造函数中声明的类的含义< > –
请参考以下两个链接(通配符:非常精美的解释)http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html和http://docs.oracle.com/javase/tutorial/ extra/generics/wildcards.html –
@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-inference-generic-instance-creation.html) – Pshemo
List<? extends SomeObject> l;
不接受new SomeObject()
但是List<SomeObject> l;
。
什么也没有工作: List<SomeObject> l = new ArrayList<SubTypeOfSomeObject>()
什么是工作: List<? extends SomeObject> l = new ArrayList<SubTypeOfSomeObject>()
作为第一个答案,
List<? extends SomeObject> l;
必须包含的对象,从SomeObject继承,而不是一些直接SomeObject。
这是错误的,该列表也可以包含一个SomeObject。 – assylias
您要阅读的关键链接是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>
等等,而不必明确创建另一个列表。
X
不能被添加到List<Y>
即使X
可以转换为Y
。
所以,在你的第二个情况下,如果List<X> l;
被允许添加X的子类,这会破坏类型安全
这是在Java教程很好解释的基本原则是:http://docs.oracle.com /javase/tutorial/extra/generics/wildcards.html –