Java generics type erasure: when and what happens?

I read about Java’s type erasure on Oracle’s website.

When does type erasure occur? At compile time or runtime? When the class is loaded? When the class is instantiated?

A lot of sites (including the official tutorial mentioned above) say type erasure occurs at compile time. If the type information is completely removed at compile time, how does the JDK check type compatibility when a method using generics is invoked with no type information or wrong type information?

Consider the following example: Say class A has a method, empty(Box<? extends Number> b). We compile and get the class file A.class.

public class A {
    public static void empty(Box<? extends Number> b) {}
public class Box<T> {}

Now we create another class B which invokes the method empty with a non-parameterized argument (raw type): empty(new Box()). If we compile with A.class in the classpath, javac is smart enough to raise a warning. So A.class has some type information stored in it.

public class B {
    public static void invoke() {
        // java: unchecked method invocation:
        //  method empty in class A is applied to given types
        //  required: Box<? extends java.lang.Number>
        //  found:    Box
        // java: unchecked conversion
        //  required: Box<? extends java.lang.Number>
        //  found:    Box
        A.empty(new Box());

My guess would be that type erasure occurs when the class is loaded, but it is just a guess. So when does it happen?

7 Answers

Leave a Comment