W
W
WTFAYD2016-08-28 15:46:59
Java
WTFAYD, 2016-08-28 15:46:59

Why is type information retained despite type erasure?

class Generic<T> {
    T obj;
    void set(T obj) { this.obj = obj; }
    T get() { return obj; }
}
public class Program {
    static public void main(String[] args) {
        Generic<String> g = new Generic<>();
        Generic<Integer> f = new Generic<>();
        g.set("String");
        f.set(123);
        System.out.println(g.get() + f.get());
    }
}

The output is, respectively, as expected, String123 . The question arises - what does the compiler do when an instance of a parameterized type is created - it looks for a .class file, initializes variables as in a regular class, but instead of T specifies Object? Then how does the compiler know the exact type parameter if the type information is erased to Object ? Is it about bridge methods ?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sland Show, 2016-08-28
@SlandShow

At first, it may seem that the JVM creates a new version of the class where and replaces T with the desired type. But in fact, the JVM partially 'tweaks' an already existing parameterized class. Including replaces T with the version of the desired value each time it is required. That is, there is one class, not several versions with fields of different types.
In your case, first the JVM corrects T obj to Object obj (which is downcast converted to String) and then again corrects String obj to Object obj (which is then also converted to Integer implicitly)


g.set("String");
f.set(123);

T obj is actually replaced with Object obj . This process is called erasure, which occurs at the compilation stage. And then there is an implicit downcast.
class Test<T> {
T val; // на самом деле T заменяется на Object
Test(T o) { val = o; }
T get() { return val; }

}

class SimpleClass {
void info() { System.out.println("я метод info() из класса SimpleClass"); }
}

Test<SimpleClass> v = new Test<>(new SimpleClass());

SimpleClass v2 = v.get(); // при инициализации v2 на самом деле происходит неявное нисходящее преобразование к нужному типу

//что происходит на самом деле:
//SimpleClass v2 = (SimpleClass) v.get();

v2.info();

Erasure of generalized types occurs at compile time. In the simplest case, an unrestricted type is erased to Object, the generic class NameClass to NameClass.
In other words, information about generics exists only at compile time and is not available at runtime.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question