What is type erasure, and what limitations does it impose?

9 minadvancedtype-erasuregenericslimitations

Quick Answer

Type erasure means the compiler enforces generic type constraints at compile time, then replaces type parameters with their bounds (or Object) in the compiled bytecode, so no generic type information exists at runtime. This means you can't do new T(), can't use instanceof with a parameterized type, can't create a generic array directly, and all instances of a generic class share one .class file regardless of their type argument.

Detailed Answer

Java generics are a compile-time only feature — the JVM itself has no concept of List<String> vs List<Integer>; both compile down to plain List (using Object, or the bound type, internally). This is type erasure: the compiler checks your generic type usage for correctness, inserts the necessary casts, and then discards the type parameter information.

Consequences / limitations:

  1. Can't create an instance of a type parameter: new T() doesn't compile — the compiler has no idea what T actually is at runtime.
  2. Can't check generic types with instanceof: if (obj instanceof List<String>) doesn't compile — only obj instanceof List (the raw type) is allowed, since the <String> information is erased.
  3. Can't create a generic array directly: new T[10] or new List<String>[10] doesn't compile, due to interactions with array covariance and erasure that could otherwise let you store the wrong type undetected.
  4. All parameterized instances share one class: List<String>.class and List<Integer>.class are the same Class object at runtime — list1.getClass() == list2.getClass() is true even for different element types.
  5. Overloading on erased types conflicts: you can't overload void foo(List<String> s) and void foo(List<Integer> i) in the same class — after erasure, both become void foo(List).

Erasure exists mainly for backward compatibility: it let pre-generics bytecode (Java 1.4 and earlier) keep working alongside generic code without a parallel, incompatible runtime type system.