Whats the use of saying <? extends SomeObject> instead of <SomeObject>
所以我查看了一些Java代码,无意中发现:
1
List<? extends SomeObject> l;
基本上,这个列表接受所有属于某个对象的对象——某个对象本身或其继承者。但根据多元论,它的继承人也可以被看作是某个物体,所以这也会起作用:
那么,当第二个选项被明确定义并且几乎相同时,为什么会有人使用第一个选项呢?
这在Java教程中得到了很好的解释:DOCS.Oracle .COM/JavaSe/Tube/Ext/泛型/Field&ZWnJ;
在这一点上,你不能说List l = new ArrayList; (不允许)在哪里
1
List<? extends SomeObject> l;
你可以说
List extends SomeObject> l = new ArrayList; (允许)
但请注意,在List extends SomeObject> l = new ArrayList; 中,您不能在列表l中添加任何内容,因为?表示未知类(当然是空类除外)。
更新:关于你在评论中的问题
现在考虑一种情况,在这种情况下,您必须编写一个函数来打印您的列表,但请注意,它必须只接受一个列表,其中包含属于someobject子类的对象。在这种情况下,如我上面所述,你不能使用
public void printList(List someList)
那你会怎么做?你想做点什么
1 2 3 4
public void printList( List<? extends SomeObject> someList) {
for ( SomeObject myObj : someList) {
//process read operations on myObj
}
你能澄清两件事吗:如果我不能在列表中添加任何内容,我可以对它做些什么?在内部构造函数中声明的类的含义是什么<>
请参考以下两个链接(通配符:解释得非常漂亮)docs.oracle.com/javase/tutorial/extra/generics/subtype.htm l和docs.oracle.com/javase/tutorial/extra/generics/widcards.htm&zwnj;&8203;l
@orcyngiser What could I possibly do with a list if I cannot add anything to it? 有时您只想读取/使用某个容器的内容而不修改它。What is the meaning of the Class stated in the constructor inside <> 不知道你在问什么。简单地说,它是泛型类型。更多信息。如果你在问有关<> 的问题,请看这里和这里。
@或是看更新后的答案。希望有帮助!也去看看pshemo在上述评论中提到的链接。它会让你更好地理解。
一个警告:代码分析检查程序(如sonarkube)将标记一个返回通用通配符作为关键"代码气味"的方法:"强烈建议不要将通配符类型用作返回类型。"因为类型推断规则相当复杂,所以该API的用户不太可能知道如何正确使用它。"rules.sonarsource.com/java/rspec-1452(规则.sonarsource.com/java/rspec-1452)
您要阅读的关键链接是http://docs.oracle.com/javase/tutorial/extra/generics/widcards.html,它详细解释了通用通配符。
List 与List extends SomeObject> 不同。注意以下事项
1 2 3 4
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
您可能需要注意的是,您可以将say字符串添加到x和y列表中,但是当您编写say库函数(例如链接中所示示例中的printcollection)而不是接受Collection 时,它将非常有用。在这种情况下,如果您接受edocx,则用户无法将其必须传递给您方法的字符串列表传递给您的方法。1〔13〕然后用户可以通过他的Collection, Collection 等,而不必显式地创建另一个列表。
List extends SomeObject> l; 不接受new SomeObject() 。但江户十一〔二〕是这样。
什么也不起作用:List l = new ArrayList()
什么有效:List extends SomeObject> l = new ArrayList()
即使X 可以转换为Y 也不能将X 添加到List 中。
因此,在第二种情况下,如果允许List l; 添加x的子类,这将打破类型安全的基本原则。
作为第一个答案,
1
List<? extends SomeObject> l;
必须包含从some object继承的对象,而不是直接someobject。
这是错误的,该列表也可以包含someobject。