Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain what does <? super T> mean and when should it be used and how this construction should cooperate with <T> and <? extends T>?

I'm using generics rather long time but I've never used construction like List<? super T>.

What does it mean? How to use it? How does it look after erasure?

I also wonder: is it something standard in generic programming (template programming?) or it's just a java 'invention'? Does c#, for example, allow similar constructions?

like image 635
Roman Avatar asked Feb 22 '10 11:02

Roman


2 Answers

This construct is used when you want to consume items from a collection into another collection. E.g. you have a generic Stack and you want to add a popAll method which takes a Collection as parameter, and pops all items from the stack into it. By common sense, this code should be legal:

Stack<Number> numberStack = new Stack<Number>();
Collection<Object> objects = ... ;
numberStack.popAll(objects);

but it compiles only if you define popAll like this:

// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
    while (!isEmpty())
    dst.add(pop());
}

The other side of the coin is that pushAll should be defined like this:

// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
    for (E e : src)
    push(e);
}

Update: Josh Bloch propagates this mnemonic to help you remember which wildcard type to use:

PECS stands for producer-extends, consumer-super.

For more details, see Effective Java 2nd Ed., Item 28.

like image 176
Péter Török Avatar answered Sep 22 '22 12:09

Péter Török


This is called "bounded wildcard". It's very well explained in the official tutorial.

As stated in the tutorial, you thus know that the list contains objects of exactly one subtype of T

For example List<? extends Number> can hold only Integers or only Longs, but not both.

like image 39
Bozho Avatar answered Sep 22 '22 12:09

Bozho