What is a difference between <? super E> and <? extends E>?

generics, java

Solution

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`.

Problem

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) ```

Original source

Related problems