library
advancedType Erasure
Understand how generics are implemented via erasure and the limitations this creates.
Java generics are implemented using type erasure: the compiler removes all generic type information after type checking, replacing type parameters with their bounds (or Object if unbounded). The compiled bytecode has no knowledge of generic types.
Erasure = writing a letter with invisible ink (generics). The recipient (JVM) can't see the invisible parts — they only see the regular ink (Object, casts).
Key Concepts
1
What erasure does:
- List<String> becomes List (raw type) in bytecode
- T becomes Object (or the bound type if bounded)
- The compiler inserts casts at call sites where generic types are used
- Bridge methods are generated for covariant overrides
2
Why erasure? Backward compatibility. Java 5 generics needed to work with pre-generics bytecode. A List<String> at runtime is just a List — this lets old code that expects List work with new generic code.
3
Limitations caused by erasure:
- No new T() — the runtime doesn't know what T is
- No instanceof T — type info isn't available
- No T.class — same reason
- No static fields of type T — statics are shared across all parameterizations
- Can't create generic arrays: new T[10] is illegal
- Can't overload by generic parameter: void process(List<String>) and void process(List<Integer>) have the same erasure
4
Workarounds: pass Class<T> as a parameter (type token), use TypeReference in Jackson, or use reflection to capture generic type info from subclass declarations.