Mi comprensión obviamente errónea de los genéricos de Java fue hasta ahora, que Type Erasure elimina toda la información de tipo, de modo que no queda nada en el tiempo de ejecución. Recientemente me encontré con un fragmento de código donde tuve que preguntarme a mí mismo: ¿Cómo funciona esto? Simplificada, se presenta como:¿Por qué no se borran todos los tipos de información en Java en tiempo de ejecución?
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);
}
}
y
public class Example {
public static void main(String[] args) {
SuperClass sc = new SuperClass<Integer>(){};
sc.tellMyType();
}
}
La ejecución de los resultados de la clase principal en Hi, my type parameter is class java.lang.Integer
.
Lo que podemos ver aquí es que la información de tipo de T también está disponible en tiempo de ejecución, lo que contradice mi comprensión inicial.
Así que mi pregunta es: ¿Por qué el compilador guarda esto? ¿Es esto necesario para algún comportamiento interno de JVM o hay alguna explicación razonable para este efecto?
Breve comentario: si su subclase simplemente pasa el tipo genérico (como en 'public class SuperList extiende ArrayList '), el resultado del código de ejemplo (sin clases anónimas involucradas) sería "Hola, mi parámetro de tipo es T" –
sfussenegger
Entonces, si hubieran omitido el '{}' en 'main' (que probablemente requeriría cambiar el constructor a public), entonces el hecho de que el parámetro type fuera' Integer' se habría perdido en el tiempo de ejecución. – MatrixFrog