Back to library

Java Generics and Wildcards

Stop sprinkling `?` until the compiler stops yelling, and start designing Java generics on purpose — one PECS rule per drop, ending with a generic utility class whose variance you can defend in code review.

Applied14 drops~2-week path · 5–8 min/daytechnology

Phase 1Why Generics Exist and What They Cost

See why generics exist and what type erasure costs.

4 drops
  1. Generics moved type checks from runtime to compile time

    6 min

    Generics moved type checks from runtime to compile time

  2. At runtime, `List<String>` and `List<Integer>` are the same class

    7 min

    At runtime, `List<String>` and `List<Integer>` are the same class

  3. `List<String>` is not a `List<Object>` — and that's intentional

    6 min

    `List<String>` is not a `List<Object>` — and that's intentional

  4. A type parameter is one variable you must use consistently

    7 min

    A type parameter is one variable you must use consistently

Phase 2Bounded and Unbounded Wildcards in Practice

Use bounded and unbounded wildcards in real code.

5 drops
  1. `List<?>` means 'a list of something I will not write into'

    6 min

    `List<?>` means 'a list of something I will not write into'

  2. `? extends T` is the producer — read up to T, do not add

    7 min

    `? extends T` is the producer — read up to T, do not add

  3. `? super T` is the consumer — add T, do not read as T

    7 min

    `? super T` is the consumer — add T, do not read as T

  4. PECS — Producer Extends, Consumer Super, Both means T

    8 min

    PECS — Producer Extends, Consumer Super, Both means T

  5. `<T extends Bound>` is a named upper bound — use it when you need the name

    8 min

    `<T extends Bound>` is a named upper bound — use it when you need the name

Phase 3PECS Across Real Java APIs

Map PECS onto Collections, Comparator, and stream APIs.

4 drops
  1. Read `Collections.copy` and you've read every PECS signature ever written

    7 min

    Read `Collections.copy` and you've read every PECS signature ever written

  2. `Comparator<? super T>` is why a `Comparator<Number>` can sort `List<Integer>`

    7 min

    `Comparator<? super T>` is why a `Comparator<Number>` can sort `List<Integer>`

  3. `Function<? super T, ? extends R>` is PECS twice in one signature

    7 min

    `Function<? super T, ? extends R>` is PECS twice in one signature

  4. Apply PECS to a real review and pick the right wildcard in 30 seconds

    8 min

    Apply PECS to a real review and pick the right wildcard in 30 seconds

Phase 4Design a Generic Utility Class

Design a generic utility class with correct variance.

1 drop
  1. Design a `Pipeline<T>` utility class with correct variance throughout

    20 min

    Design a `Pipeline<T>` utility class with correct variance throughout

Frequently asked questions

What does PECS stand for in Java generics?
This is covered in the “Java Generics and Wildcards” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
When do I use `? extends T` versus `? super T`?
This is covered in the “Java Generics and Wildcards” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
Why can't I add elements to a `List<? extends Number>`?
This is covered in the “Java Generics and Wildcards” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
What is type erasure and why does it matter?
This is covered in the “Java Generics and Wildcards” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
Are Java generics covariant or invariant?
This is covered in the “Java Generics and Wildcards” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.