All topics
library
intermediate

Bounded Type Parameters & Wildcards

Know the difference between <T extends X>, <? extends X>, <? super X>, and PECS (Producer Extends, Consumer Super).

Bounded type parameters restrict what types can be used as generic arguments:

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
Upper bounded: <T extends Number> — T must be Number or a subtype. Used in class/method declarations to constrain the type parameter.
2
Wildcards are used at use-site (method parameters, variables) when you don't care about the exact type:
3
<? extends Number> (upper bounded wildcard) — accepts Number or any subtype. You can read from it (returns Number) but can't write to it (compiler doesn't know the exact type). This is a Producer — it produces values.
4
<? super Integer> (lower bounded wildcard) — accepts Integer or any supertype (Number, Object). You can write Integer to it but reading returns Object. This is a Consumer — it consumes values.
5
<?> (unbounded wildcard) — equivalent to <? extends Object>. Read returns Object, can't write (except null).
6
PECS principle (from Effective Java): Producer Extends, Consumer Super. If the parameterized type produces T values (you read from it), use extends. If it consumes T values (you write to it), use super. If it does both, use exact type (no wildcard).
7
Example: Collections.copy(List<? super T> dest, List<? extends T> src) — src produces (extends), dest consumes (super).