2011-11-04 16 views
5

Existen otras preguntas relacionadas, p. 6624113, 3403909, 4516891 pero mi pregunta es más simple y más específica.Uso de getActualTypeArguments en un contexto genérico

Quiero saber en tiempo de ejecución con qué tipo se parametrizó mi clase - Quiero un objeto de clase del tipo del parámetro de tipo. Debido a la borradura de tipo, la expresión T.class no funciona, y no hay una función como typeof(T) en C# para obtenerla.

Sin embargo, hay algo de "súper-reflexión" disponible a través de ParameterizedType y clases relacionadas, lo que me lleva casi todo el camino hasta allí.

import java.lang.reflect.ParameterizedType; 

public class MyClass<T> { 
    public static void main(String[] args) { 
     new MyClass<Integer>().printTypeParam(); 
    } 

    public void printTypeParam() { 
     class DummyT extends MyClass<T> {} 
     class DummyString extends MyClass<String> {} 

     ParameterizedType ptT = 
      ((ParameterizedType) DummyT.class.getGenericSuperclass()); 

     ParameterizedType ptString = 
      ((ParameterizedType) DummyString.class.getGenericSuperclass()); 

     System.out.println("DummyT: " + ptT + " " + ptT.getActualTypeArguments()[0]); 
     System.out.println("DummyString: " + ptString + " " + ptString.getActualTypeArguments()[0]); 

    } 
} 

Cuando corro lo anterior que ver esta salida:

DummyT: MyClass<T> T 
DummyString: MyClass<java.lang.String> class java.lang.String 

Como se puede ver, esto funciona para cuando los argumentos de tipo se conocen en tiempo de compilación en la línea de código que contiene la llamada a getGenericSuperClass, pero cuando esa llamada se trata de medicamentos genéricos simplemente imprime el nombre del parámetro de tipo.

¿Hay alguna manera de obtener la primera línea para imprimir java.lang.Integer en lugar de T?

Respuesta

3

No puede, simple y llanamente. Integer no está reificado, es completamente erased. Si no me cree, compile el archivo una vez con Integer y una vez con Long. Los dos archivos de clase binarios serán absolutamente idénticos.

La borradura de tipo es una dura realidad que no podrá sortear. Te sugiero que vuelvas a pensar por qué necesitas en lugar de ir por el camino de introducir hacks para tratar de evitar.

útiles AngelikaLanger genéricos FAQ temas:

+1

De hecho, me hicieron lo que usted sugiere, y usted será sorprendido de escuchar que tiene razón: 2 archivos se crean: MyClass $ 1DummyString.class MyClass $ 1DummyT.class MyClass.class y son idénticas en binario si cambio el tipo en la línea 5 a Long en lugar de f Entero. –

+0

Estoy felizmente usando la solución/patrón de pasar una instancia de clase al constructor. Tenía curiosidad sobre si la solución menos detallada era posible. –

Cuestiones relacionadas