All topics
library
advanced

Type 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.