What is PECS (Producer Extends, Consumer Super)?
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));
}
}
srcis a producer ofT(the method only reads from it) →? extends T.destis a consumer ofT(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.