The real reason that you can write ? extends Fruit is so you can write your own generic classes. For example, consider the dummy stack implementation below that uses bounded wildcards to increase API flexibility.
class DummyStack<T> {
private final List<T> stackElements = new ArrayList<T>();
public void pushAll(Collection<? extends T> collection) {
for (T item : collection) {
stackElements.add(item);
}
}
public void popAll(Collection<? super T> collection) {
for (T item : stackElements) {
collection.add(item);
}
}
// Other methods go here
}
This contrived class (JDK contains its own Stack) has two methods of interest: popAll(...) and pushAll(...). pushAll loads stuff onto the stack and uses ? extends E as we're adding to the stack anything that is an E or extends E. popAll converts the stack into a collection and uses ? super E as we're consuming anything from our stack that is an E or a super-class of E.
The code below shows how to use the fake stack class:
public static void checkingFruit() {
List<Fruit> fruit = new ArrayList<Fruit>();
fruit.add(new Fruit());
fruit.add(new Apple());
fruit.add(new Orange());
DummyStack<Fruit> handler = new DummyStack<Fruit>();
handler.pushAll(fruit);
handler.popAll(fruit);
}
public static void checkingApples() {
List<Apple> apples = new ArrayList<Apple>();
apples.add(new Apple());
DummyStack<Fruit> handler = new DummyStack<Fruit>();
handler.pushAll(apples); // allowed as Apple extends Fruit
// handler.popAll(apples); // not allowed...
DummyStack<Apple> handler2 = new DummyStack<Apple>();
handler2.pushAll(apples);
handler2.popAll(apples); // allowed in '? super T' as Fruit is super of
// Apple
}
The basic premise used to decide whether to use ? extends E or ? super E is this. If the other object is giving your object something (a source) then use ? extends E. If the other object is receiving stuff from your object (a destination) then use ? super E.
No comments:
Post a comment