Tuesday, January 31, 2012

Java bounded wildcards

From Effective Java, 2nd edition

For maximum flexibility, use wildcard types on input parameters that represent producers or consumers.
Mnemonic:
PECS stands for producer-extends, consumer-super.

E.g., method that takes a sequence of elements and pushes them all onto the stack:
// pushAll method without wildcard type - deficient!
public void pushAll(Iterable<E> src) {
    for (E e : src) {
        push(e);
    }
}
should be re-written:
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
    for (E e : src) {
        push(e);
    }
}
Similarly, a method that pops each element off the stack and adds the elements to the given collection:
// popAll method without wildcard type - deficient!
public void popAll(Collection<E> dst) {
    while (!isEmpty()) {
        dst.add(pop());
    }
}
should be re-written:
// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
    while (!isEmpty()) {
        dst.add(pop());
    }
}