What is PECS (Producer Extends, Consumer Super)?

8 minadvancedpecsgenericswildcards

Quick Answer

PECS is a mnemonic for choosing generic wildcards in method parameters: if a parameterized type only produces (you read from) values, use ? extends T; if it only consumes (you write into) values, use ? super T; if it does both, use an exact type T with no wildcard. Collections.copy(dest, src) is the textbook example, using ? super T for the destination and ? extends T for the source.

Detailed Answer

PECS — "Producer extends, Consumer super" — is Joshua Bloch's mnemonic (from Effective Java) for picking the right wildcard on a generic method parameter:

  • If the parameter is a producer — your method only reads values out of it — use ? extends T.
  • If the parameter is a consumer — your method only writes values into it — use ? super T.
  • If it does both, don't use a wildcard at all — use the exact type T.

The textbook example is Collections.copy:

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
    for (int i = 0; i < src.size(); i++) {
        dest.set(i, src.get(i));
    }
}
  • src is a producer of T (the method only reads from it) → ? extends T.
  • dest is a consumer of T (the method only writes into it) → ? super T.

This lets you call copy(List<Object>, List<Integer>) even though List<Object> isn't a List<Integer> and vice versa — without PECS-style wildcards, generics' lack of subtyping between List<Integer> and List<Object> would make such a utility method far less reusable.

PECS is the practical reasoning behind the read/write restrictions on ? extends/? super covered by wildcard generics — it's less something to memorize abstractly and more a direct consequence of what's actually type-safe to do with each.