library
intermediateGenerics & Type Erasure
Understand how Java generics work at compile time, why they're erased at runtime, and common pitfalls.
Java generics (Java 5) provide compile-time type safety for collections and other parameterized types. Due to backward compatibility, generic type information is erased at runtime (type erasure).
Generics = labeled storage boxes at a warehouse. At checkout (compile time), the label (type) is verified. During shipping (runtime), the label is removed (erasure) — the box is just a generic container.
Key Concepts
1
Type erasure:
- List<String> becomes List at runtime
- T becomes Object (or the upper bound if specified)
- Bridge methods are generated for covariant return types
2
Consequences:
- Can't do: new T(), T.class, instanceof List<String>
- Can't create generic arrays: new T[10] — use Array.newInstance or List<T>
- At runtime, List<String> and List<Integer> are the same class
3
Wildcards:
- ? extends T (upper bound): read-only (producer). List<? extends Number> can hold List<Integer>
- ? super T (lower bound): write-only (consumer). List<? super Integer> can accept Integer
- PECS: Producer Extends, Consumer Super
4
Bounded type parameters:
- <T extends Comparable<T>>: T must be Comparable
- <T extends Number & Serializable>: multiple bounds (class first, then interfaces)
5
Type tokens: pass Class<T> to work around erasure: <T> T parse(String json, Class<T> type)