What is the difference between <? super E>
and <? extends E>
?
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)
and for one for the method:
public int drainTo(Collection<? super E> c)
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.)
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
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
.
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
.