PECS Principle

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • PECS stands for Producer extends, Consumer super.
  • 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.