Мое, очевидно, неправильное понимание Java Generics было до сих пор, что Type Erasure удаляет всю информацию о типе, так что во время выполнения ничего не осталось. Недавно я наткнулся на фрагмент кода, где я должен был спросить себя: как этот хак делает это? Упрощенный, он представлен как:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public abstract class SuperClass<T> {
private final Type type;
protected SuperClass(){
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperclass();
type = parameterizedType.getActualTypeArguments()[0];
}
public void tellMyType(){
System.out.println("Hi, my type parameter is " + type);
}
}
и
public class Example {
public static void main(String[] args) {
SuperClass sc = new SuperClass<Integer>(){};
sc.tellMyType();
}
}
Выполнение основного класса приводит к Hi, my type parameter is class java.lang.Integer
.
Здесь мы видим, что информация о типе T также доступна во время выполнения, что противоречит моему первоначальному пониманию.
Итак, мой вопрос: почему компилятор сохраняет это? Требуется ли это для некоторого внутреннего поведения JVM или есть ли разумное объяснение этого эффекта?