< 和有什么区别?超级E>和 <?扩展E>? [英] What is a difference between <? super E> and <? extends E>?
问题描述
<有什么区别?super E>
和 ?
例如,当您查看类 java.util.concurrent.LinkedBlockingQueue
时,构造函数具有以下签名:
For instance when you take a look at class java.util.concurrent.LinkedBlockingQueue
there is the following signature for the constructor:
public LinkedBlockingQueue(Collection<? extends E> c)
对于方法之一:
public int drainTo(Collection<? super E> c)
推荐答案
第一个 ( super E>
) 说它是某种类型,它是 E 的祖先(超类)";;第二个( extends E>
)说它是某种类型,它是 E 的子类".(在这两种情况下,E 本身都可以.)
The first (<? super E>
) says that it's "some type which is an ancestor (superclass) of E"; the second (<? extends E>
) says that it's "some type which is a subclass of E". (In both cases E itself is okay.)
所以构造函数使用了 ?扩展 E
形式,因此它保证当它从集合中获取值时,它们都将是 E 或某个子类(即它是兼容的).drainTo
方法试图将值放入集合中,因此集合必须具有 E
或超类的元素类型.
So the constructor uses the ? extends E
form so it guarantees that when it fetches values from the collection, they will all be E or some subclass (i.e. it's compatible). The drainTo
method is trying to put values into the collection, so the collection has to have an element type of E
or a superclass.
举个例子,假设你有一个这样的类层次结构:
As an example, suppose you have a class hierarchy like this:
Parent extends Object
Child extends Parent
和 LinkedBlockingQueue
.您可以在 List
中构造这个传递,它将安全地复制所有元素,因为每个 Child
都是一个父级.您无法传入 List
,因为某些元素可能与 Parent
不兼容.
and a LinkedBlockingQueue<Parent>
. You can construct this passing in a List<Child>
which will copy all the elements safely, because every Child
is a parent. You couldn't pass in a List<Object>
because some elements might not be compatible with Parent
.
同样,您可以将该队列排入 List
因为每个 Parent
都是一个 Object
...但你不能将它排入 List
因为 List
期望它的所有元素都与 Child
兼容.
Likewise you can drain that queue into a List<Object>
because every Parent
is an Object
... but you couldn't drain it into a List<Child>
because the List<Child>
expects all its elements to be compatible with Child
.
这篇关于< 和有什么区别?超级E>和 <?扩展E>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!