Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics type erasure in Java

Here's the code:

public class Main {
    public static void main(String[] args) {
        Gen<Integer> g = new Gen<Integer>(5);

        System.out.println(g.getClass());
        System.out.println(g.ob.getClass());
    }
}

class Gen<T> {
    T ob;

    public Gen(T x) {
        ob = x;
    }
}

And here's the output

class Gen               // This I understand
class java.lang.Integer // But if type erasure is happening, shouldn't this be java.lang.Object?

I get it that Type parameter T is erased at runtime, but then why is the type parameter of ob surviving at runtime?

like image 279
Ramanlfc Avatar asked Oct 16 '15 18:10

Ramanlfc


2 Answers

Nope!

Consider this:

Object x = new Integer(1);
System.out.println(x.toString());

You'll get 1.

But shouldn't I get Object.toString()?

No. While x is a reference of type Object, the actual referent is an Integer, so at run-time, the Integer implementation of toString is called.

It is the same for getClass.

like image 138
sdgfsdh Avatar answered Oct 09 '22 23:10

sdgfsdh


Type erasure is happening. Generics are a compile time type checking system. At run-time you still get the class (it is run-time type information). The linked Type erasure documentation says (in part)

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.

Your instance has a type, it's Object. But an Object reference can refer to any sub-class (which is every class) in Java. You get the type it refers to.

like image 40
Elliott Frisch Avatar answered Oct 10 '22 00:10

Elliott Frisch