Java Generics (Wildcards)
In your first question, <? extends T>
and <? super T>
are examples of bounded wildcards. An unbounded wildcard looks like <?>
, and basically means <? extends Object>
. It loosely means the generic can be any type. A bounded wildcard (<? extends T>
or <? super T>
) places a restriction on the type by saying that it either has to extend a specific type (<? extends T>
is known as an upper bound), or has to be an ancestor of a specific type (<? super T>
is known as a lower bound).
The Java Tutorials have some pretty good explanations of generics in the articles Wildcards and More Fun with Wildcards.
If you have a class hierarchy A, B is a subclass of A, and C and D both are subclass of B like below
class A {}class B extends A {}class C extends B {}class D extends B {}
Then
List<? extends A> la;la = new ArrayList<B>();la = new ArrayList<C>();la = new ArrayList<D>();List<? super B> lb;lb = new ArrayList<A>(); //finelb = new ArrayList<C>(); //will not compilepublic void someMethod(List<? extends B> lb) { B b = lb.get(0); // is fine lb.add(new C()); //will not compile as we do not know the type of the list, only that it is bounded above by B}public void otherMethod(List<? super B> lb) { B b = lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A lb.add(new B()); // is fine, as we know that it will be a super type of A }
A bounded wildcard is like ? extends B
where B is some type. That is, the type is unknown but a "bound" can be placed on it. In this case, it is bounded by some class, which is a subclass of B.
Josh Bloch also has a good explanation of when to use super
and extends
in this google io video talk where he mentions the Producer extends
Consumer super
mnemonic.
From the presentation slides:
Suppose you want to add bulk methods to
Stack<E>
void pushAll(Collection<? extends E> src);
– src is an E producer
void popAll(Collection<? super E> dst);
– dst is an E consumer