关于java:什么是使用说<?

Whats the use of saying <? extends SomeObject> instead of <SomeObject>

所以我查看了一些Java代码,无意中发现:

1
List<? extends SomeObject> l;

基本上,这个列表接受所有属于某个对象的对象——某个对象本身或其继承者。但根据多元论,它的继承人也可以被看作是某个物体,所以这也会起作用:

1
List<SomeObject> l;

那么,当第二个选项被明确定义并且几乎相同时,为什么会有人使用第一个选项呢?


1
List<SomeObject> l;

在这一点上,你不能说List l = new ArrayList;(不允许)在哪里

1
List<? extends SomeObject> l;

你可以说

List l = new ArrayList;(允许)

但请注意,在List 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
        }


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

ListList不同。注意以下事项

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 l;不接受new SomeObject()。但江户十一〔二〕是这样。

什么也不起作用:List l = new ArrayList()

什么有效:List l = new ArrayList()


即使X可以转换为Y也不能将X添加到List中。

因此,在第二种情况下,如果允许List l;添加x的子类,这将打破类型安全的基本原则。


作为第一个答案,

1
List<? extends SomeObject> l;

必须包含从some object继承的对象,而不是直接someobject。