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?
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.
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 Integer
s or only Long
s, but not both.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With