PECS Principle
TL;DR
- PECS stands for Producer
extends, Consumersuper. - It is a mnemonic created by Joshua Bloch (author of Effective Java) to help developers remember when to use which wildcard.
- If an object produces/returns items to you, use
? extends T. - If an object consumes/accepts items from you, use
? super T.
Concept
When writing methods that accept collections, developers often struggle to decide between <? extends T>, <? super T>, or just <T>. PECS solves this.
1. Producer extends
If the collection’s job is to give you data (it Produces data), use ? extends T.
You can safely read Ts from it, but you cannot write to it.
2. Consumer super
If the collection’s job is to take data from you (it Consumes data), use ? super T.
You can safely write Ts to it, but you cannot read from it (except as Object).
Examples
Let’s say we have a method that copies elements from a source list to a destination list.
- The source list is the Producer (we get items from it).
- The destination list is the Consumer (we put items into it).
import java.util.ArrayList;
import java.util.List;
public class PecsExample {
// SRC produces data -> extends
// DEST consumes data -> super
public static <T> void copy(List<? extends T> src, List<? super T> dest) {
for (T item : src) {
dest.add(item); // Write to consumer
}
}
public static void main(String[] args) {
List<Integer> ints = List.of(1, 2, 3);
List<Number> nums = new ArrayList<>();
List<Object> objs = new ArrayList<>();
// We can copy Integers into a list of Numbers
copy(ints, nums);
// We can copy Integers into a list of Objects
copy(ints, objs);
System.out.println(nums); // [1, 2, 3]
System.out.println(objs); // [1, 2, 3]
}
}
Interview Questions
Q: What should you do if a collection is BOTH a producer and a consumer?
A: If a collection needs to both produce data and consume data in the exact same method, you should not use wildcards at all. You must use the exact generic type (e.g., List<T>). Wildcards are strictly for variables that are read-only (extends) or write-only (super).
Q: Where is PECS most famously used in the Java Standard Library?
A: It is used in java.util.Collections.copy(List<? super T> dest, List<? extends T> src). The Java API designers followed the PECS principle perfectly to ensure maximum flexibility for developers using the copy utility.