Generics and wildcards
Read ? extends and ? super without guessing, using one rule you can say out loud.
Open this lesson in the learning hubKey points
- A type parameter makes a collection checked at compile time: a
List<String>can never hold an Integer. List<? extends Number>produces numbers. You may read them; you may not add anything to it.List<? super Integer>consumes integers. You may add them; whatever you read back is anObject.- PECS: Producer Extends, Consumer Super. Wildcards belong on parameters, rarely on return types.
List<?>means some unknown element type. Size and iteration still work; adding does not.- Generics are erased at runtime, so two differently typed lists are the same class once compiled.
Example
import java.util.*;
public class Main {
// Produces values for us to read, so: ? extends
static double sum(List<? extends Number> nums) {
double total = 0;
for (Number n : nums) total += n.doubleValue();
return total;
}
// Consumes values we hand it, so: ? super
static void fillWithInts(List<? super Integer> sink) {
for (int i = 1; i <= 3; i++) sink.add(i);
}
public static void main(String[] args) {
List<Integer> ints = List.of(1, 2, 3);
List<Double> doubles = List.of(1.5, 2.5);
System.out.println("sum(List<Integer>) : " + sum(ints));
System.out.println("sum(List<Double>) : " + sum(doubles));
List<Number> numbers = new ArrayList<>();
fillWithInts(numbers);
List<Object> objects = new ArrayList<>();
fillWithInts(objects);
System.out.println("filled List<Number>: " + numbers);
System.out.println("filled List<Object>: " + objects);
List<?> unknown = ints;
System.out.println("List<?> size : " + unknown.size() + " (readable, nothing can be added)");
System.out.println("erasure at runtime : " +
(new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass()));
System.out.println("PECS : producer extends, consumer super");
}
}
Producer extends, consumer super — say it once and wildcards stop being a puzzle.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Collections course, and every lesson in it is listed on the Collections contents page.