views:

2703

answers:

3

I have a couple of questions about java generics wildcards:

1) whats the difference between List<? extends T> and List<? super T>

2) What is a bounded wildcard and what is an unbounded wildcard?

Thanks!

+13  A: 

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.

Bill the Lizard
Just to get it right, if A < B and B < C then: <A extends C> is wrong?
Pablo Fernandez
If by A < B, you mean A extends B, then A does extend C. You wouldn't use that in the wildcard syntax though, you'd say <? extends C> to limit your choices to either A or B.
Bill the Lizard
and in that case if I say <? super C> what would be the difference?
Pablo Fernandez
Just wanted to recommend another reference on Java Generics: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Zach Scrivena
+1  A: 

If you have a class hierarchy A, B a subclass of A and C ad D, both subclasses of B:

List<? extends A> la;
la = new ArrayList<B>();
la = new ArrayList<C>();
la = new ArrayList<D>();

List<? super B> lb;
lb = new ArrayList<A>(); //fine
lb = new ArrayList<C>(); //will not compile

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

oxbow_lakes
+8  A: 

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

Bedwyr Humphreys
I've read Bloch's book, but I still can't see the difference between extends and super in this particular case.
Pablo Fernandez
Watch the video, I think it's pretty clear. Also, I think you should ask another question on this "what's the difference between List<? extends T> and List<? super T>" where you will hopefully get more answers. (if you do, add a link from here)
Bedwyr Humphreys
Beds--why not include the example in this answer to make it complete and stand alone. Links are ephemeral.
James Schek