library
intermediateBounded Type Parameters & Wildcards
Know the difference between <T extends X>, <? extends X>, <? super X>, and PECS (Producer Extends, Consumer Super).
A bound restricts which types are allowed. A wildcard says you do not care about the exact type, only the direction.
extends = a vending machine (produces snacks — you can take items out but can't put your own in). super = a recycling bin (consumes items — you can put things in but what you get out is just 'Object').
Key Concepts
1
<T extends Number> a declaration: T must be a Number
<? extends Number> a use: some unknown subtype of Number
<? super Integer> a use: some unknown supertype of Integer
<?> a use: some unknown type2
extends lets you read.
double sum(List<? extends Number> nums) {
double t = 0;
for (Number n : nums) t += n.doubleValue(); // reading is fine
nums.add(1); // will not compile
return t;
}extends
3
You cannot add, because the list might be a List<Double> and your Integer would corrupt it. The compiler
knows only that every element is a Number.
List<Double>IntegerNumber
4
super lets you write.
void fill(List<? super Integer> dest) {
dest.add(1); // fine -- Integer fits any supertype
Integer i = dest.get(0); // will not compile
}super
5
You can add an Integer, because the list holds Integer or something broader. Reading gives you Object,
since that is all the compiler can guarantee.
IntegerObject
6
PECS: Producer Extends, Consumer Super. If the parameter gives you values, use extends. If it
takes values from you, use super.
extendssuper
7
static <T> void copy(List<? super T> dest, List<? extends T> src)8
src produces, so extends. dest consumes, so super. That one signature is the whole rule.
srcextendsdestsuper
9
<?> is the read-only case. You can read Object and write nothing but null — useful for a method
that only needs the size or wants to print the contents.
<?>Objectnull
10
Why any of this is needed. Generics are invariant: List<String> is not a List<Object>, even though a
String is an Object. Wildcards are how you get the flexibility back without the hole that invariance
closed.
List<String>List<Object>StringObject
11
The bound can also be multiple:
<T extends Number & Comparable<T>>12
Class first, then interfaces.
13
What the interviewer is probing.1. "What does PECS stand for and when do you apply it?" Probing: whether you can use it, not
recite it. Stalls: "Producer extends, consumer super." Moves up: the application: a parameter
you read from takes extends, one you write to takes super — Collections.copy(List<? super T> dest,
List<? extends T> src).
14
2. "Why can you not add to a List<? extends Number>?" Probing: why extends is read-only.
Stalls: "You should be able to, Integer is a Number." Moves up: the list might be a
List<Double>, and the compiler only knows every element is a Number, not which subtype it accepts.
15
3. "What can you read out of a List<? super Integer>?" Probing: the other half of the rule.
Stalls: "Integers." Moves up: Object — the list holds Integer or something broader, so Object is
all the compiler can guarantee.
16
4. "What is the difference between <T extends Number> and <? extends Number>?" Probing:
declaration site versus use site. Stalls: "They are the same." Moves up: the first declares a
type parameter you can refer to by name; the second is a wildcard at a use site where you do not
need to name the type.