Module 1: Generics & Type Safety in Depth
1.2 Wildcards & The PECS Rule in Practice
Estimated reading & practice time: ~20 minutes
Learning Objectives
• Apply the PECS rule (Producer Extends, Consumer Super).
• Write flexible API methods that accept collections of subtypes.
• Understand when and why lower bounds (`? super`) are essential.
Mental Model & Analogy
PECS is like a kitchen pantry: If a shelf produces ingredients for your recipe, any shelf with food or its gourmet subtypes will do (`? extends Food`). But if you are putting washed dishes into a cabinet, the cabinet must be capable of holding dishes or general household items (`? super Dish`).
Core Concept Breakdown
Joshua Bloch summarized wildcards in Effective Java: **PECS stands for Producer Extends, Consumer Super**.
1. **Producer (`? extends T`)**: If a parameterized type represents a producer that only gives you values, use `? extends T`. You can read items as `T`, but you cannot add items into the collection because the compiler cannot guarantee the exact subtype.
2. **Consumer (`? super T`)**: If a parameterized type represents a consumer that takes values you provide, use `? super T`. You can safely write items of type `T` into it.
3. **Unbounded (`?`)**: Use when only reading `Object` properties like size or clear.
Architecture Diagram
Code Example
JAVA Example
import java.util.*;
public class PecsDemo {
// Producer: reads items from numbers, calculates sum
public static double sumOfNumbers(List<? extends Number> list) {
double sum = 0.0;
for (Number n : list) {
sum += n.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(10, 20, 30);
List<Double> doubles = Arrays.asList(1.5, 2.5, 3.5);
System.out.println("Integer Sum: " + sumOfNumbers(ints));
System.out.println("Double Sum: " + sumOfNumbers(doubles));
}
}Line-by-Line Walkthrough
• `List<? extends Number>` accepts both `List<Integer>` and `List<Double>`.
• Inside the loop, elements are read safely as `Number` without runtime errors.
Integer Sum: 60.0 Double Sum: 7.5
Common Pitfalls & Debugging
• Calling `list.add(...)` on a `List<? extends Number>` parameter: this causes a compile-time error because Java does not know if the actual list is an `ArrayList<Double>` or `ArrayList<Long>`.
Try It Yourself — Java Sandbox
Live ExecutionWrite a method `copyList(List<? extends T> src, List<? super T> dest)` that copies all elements from `src` into `dest`.
Solution.java
Edit the code and click Run Code to verify output directly inside TBLearn.
1
Terminal Output
Click "Run Code" or press Ctrl+Enter to execute.
Knowledge Checkpoint • Earn +40 Credits
Test Yourself Before Moving Forward
Short, practical questions tied directly to this section. Passing awards Credits toward course discounts and interview packs.
Module 1 Checkpoint: Collections & Generics
Verify `ArrayList` vs `HashMap`, `equals`/`hashCode` contracts, and generic type safety.