Mastery
Mastery/Java/B. Generics
T1 · high-leverage

Bounded wildcards and PECS ("Producer Extends, Consumer Super")

List<? extends Number> — you can read Numbers out of it, but can't add anything (the compiler doesn't know the exact subtype, so any add could be unsafe). List<? super Integer> — you can write Integers into it, but reads only guarantee Object. Rule of thumb: if a parameter only produces values for you to consume, use extends; if it only consumes values you hand it, use super.

java
import java.util.*;

// consumer of Integer -> use `super`
static void addNumbers(List<? super Integer> dst, List<Integer> src) {
    for (Integer i : src) dst.add(i);
}

// producer of Number -> use `extends`
static double sumNumbers(List<? extends Number> src) {
    double total = 0;
    for (Number n : src) total += n.doubleValue();
    return total;
}

List<Object> objs = new ArrayList<>();
addNumbers(objs, List.of(1, 2, 3));
System.out.println("PECS 'super' (write Integers into List<Object>): " + objs);

System.out.println("PECS 'extends' (read Numbers from List<Double>): " + sumNumbers(List.of(1.5, 2.5, 3.0)));
System.out.println("same method also accepts List<Integer>:          " + sumNumbers(List.of(1, 2, 3)));

Interview angle

Frequently tested by asking a candidate to write a generic copy or transform utility's signature, to see whether they reach for ? extends/? super correctly rather than over-constraining with an exact type parameter. It's a strong, practical signal of real API-design experience versus textbook generics knowledge that never got applied to an actual method signature.

In the industry

The java.util.Collections API (copy, max, addAll) is essentially a PECS reference implementation, and well-designed generic library methods across the ecosystem follow the same shape. In code review on library-quality Java code, an overly rigid generic signature that forces callers into unnecessary casts or duplicate overloads is a routine, specific comment — "this should probably be ? extends T."