All 15 Generics questions
More in Generics
Advertisement
Java › Generics

How do bounded wildcards (? extends T and ? super T) work, and what does the PECS (Producer Extends, Consumer Super) mnemonic mean for choosing between them?

Advanced

Answer

? extends T (an upper-bounded wildcard) means the parameterized type is T or some unknown subtype of T, letting you safely READ elements as T (since whatever the actual type is, it's guaranteed to be a T or subtype) but not safely WRITE to it (since the compiler can't verify what you're adding matches the actual unknown specific subtype); ? super T (a lower-bounded wildcard) means the parameterized type is T or some unknown supertype of T, letting you safely WRITE elements of type T into it (since any supertype of T can safely accept a T) but reads only guarantee an Object -- PECS captures this: use extends when a structure is a PRODUCER you only read from, use super when it's a CONSUMER you only write to.
// PECS in action: copying from a producer (extends) to a consumer (super)
public static <T> void copy(List<? extends T> source, List<? super T> destination) {
    for (T item : source) {  // safe to READ as T from the producer
        destination.add(item);  // safe to WRITE T into the consumer
    }
}

List<Integer> ints = List.of(1, 2, 3);
List<Number> numbers = new ArrayList<>();
copy(ints, numbers);  // works: List<Integer> extends Number-compatible, List<Number> accepts Integer
Real-world example The JDK's own Collections.copy(List<? super T> dest, List<? extends T> src) method signature is a canonical real-world application of PECS, precisely allowing a List<Object> destination to receive elements copied from a List<String> source, a combination that wouldn't be possible without these bounded wildcards given generics' invariance.

Common follow-ups: Why can't you call add() on a List<? extends T> reference, even though the underlying list clearly supports adding elements of its actual concrete type?;How does PECS relate to the broader concept of covariance and contravariance in type systems?