← Back to Java

Type Erasure in Generics

JavaSeniorjava

The Question

What is type erasure in Java generics?

What a Strong Answer Covers

  • compiler removes generic type info at compile time
  • type params replaced with Object or bound
  • backward compatibility
  • cannot use instanceof with parameterized types
  • cannot create generic arrays
  • List<String> == List<Integer> at runtime
  • bridge methods

Senior-Level Answer

Type erasure is the mechanism by which the Java compiler removes all generic type parameters from the bytecode it produces. The resulting .class file contains no information about the specific type arguments used — only the erasure (the raw type or the bound) remains. This was a deliberate compatibility decision: generics were added to Java 5 without requiring changes to the JVM or breaking pre-existing bytecode.

During compilation, the compiler replaces each unbounded type parameter T with Object, and each bounded type parameter <T extends Comparable<T>> with Comparable. All casts necessary for type safety are inserted by the compiler at call sites. The programmer never writes these casts; the compiler guarantees they are correct based on the compile-time generic types.

The practical consequences of type erasure:

1. No runtime type information: List<String> and List<Integer> are the same type at runtime — both are just List. You cannot write obj instanceof List<String> or cast to List<String> safely if the source is untyped. Unchecked casts produce an unchecked cast warning rather than a compile error, because the compiler knows it cannot verify the runtime type.

2. No generic arrays: new T[10] is illegal. The JVM creates the array with the erased type at runtime, which would be Object[], defeating type safety.

3. No instantiation of type parameters: new T() is illegal because T is not known at runtime. Workarounds involve passing a Class<T> token or a Supplier<T> factory.

4. No overloading by generic parameter: void process(List<String> l) and void process(List<Integer> l) have the same erasure (void process(List l)) and cannot coexist.

5. Bridge methods: when a subclass overrides a generic method with a specific type, the compiler generates a synthetic bridge method with the erased signature that delegates to the typed override, maintaining polymorphism correctly.

Heap pollution is a related concept: a variable of parameterized type can refer to an object that is not of that type, producing a ClassCastException at an unexpected location far from the problematic cast.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly explains that type parameters are replaced with Object or bounds in bytecode, and names at least two practical consequences (instanceof, array creation, overloading).

3/3 — Strong Answer

Covers the historical compatibility rationale, all four practical constraints (instanceof, new T[], overloading, no runtime reification), bridge methods, and heap pollution.

Common Mistakes

  • Thinking type erasure is a bug or oversight — it was a deliberate design for backward compatibility with pre-Java 5 bytecode and the JVM.
  • Not knowing why overloading on generic type parameter alone is illegal — both methods erase to the same signature.
  • Not understanding bridge methods — without them, overriding a generic method in a subclass with a concrete type would break polymorphism at the bytecode level.

Follow-Up Questions

  • What is a bridge method and when does the compiler generate one? — When a class overrides a generic method with a specific type (e.g., compareTo(String) implementing Comparable<String>), the compiler generates a synthetic bridge method with the erased signature (compareTo(Object)) that casts and delegates to the typed method.
  • What is heap pollution in the context of generics? — Heap pollution occurs when a parameterized type variable refers to an object of a different parameterized type. It can lead to ClassCastException far from the problematic assignment, often caused by unchecked casts or mixing generics with raw types.
  • How do you work around type erasure when you need the runtime Class of T? — Pass a Class<T> token to the constructor or method: new Repository<>(User.class). Store it as a field and use it for instanceof checks (clazz.isInstance(obj)), array creation (Array.newInstance), or reflection-based instantiation.

Related Questions

  • JVM vs JRE vs JDK
  • Java Platform Independence
  • How JVM Works
  • Main Features of Java
  • public static void main

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout