2011-04-26 10 views
11

¿Cómo puedo obtener la clase "real" de un tipo genérico?Obtenga una clase "real" de tipo genérico

Por ejemplo:

public class MyClass<T> { 
    public void method(){ 
     //something 

     System.out.println(T.class) //causes a compile error, I wont the class name 

     //something 
    } 
} 

Si T = Entero

de salida:

java.lang.Integer 

Si T = cadena

de salida:

java.lang.String 

Gracias

+2

Puede obtener esto a través de la reflexión. PERO ... tenga en cuenta que si tiene que tratar sus datos de manera diferente según su tipo genérico, lo está haciendo mal. No deberías tener que hacerlo. Si es necesario, no es tan genérico como cree que es, y eso significa que hay un problema en su clase. – corsiKa

+1

@glowcoder: Un ejemplo donde esto podría ser válido, lo cual me he encontrado a mí mismo, es acceder a una propiedad estática del tipo genérico. Una solución consiste en definir una instancia que nunca se usa realmente, como 'T obj;', por lo que puede decir 'obj.static_property' más adelante. Además, puede hacer '((T) null) .static_property'. – mellamokb

+0

Si tiene un objeto de ese tipo, puede llamar al método 'getClass' en ese objeto. No estoy seguro si eso ayuda. –

Respuesta

21

Si tiene una variable de instancia de tipo T en su clase, y que pasa a ser establecido, entonces se podría imprimir la clase de esa variable.

public class Test<T> { 

    T var; 

    public static void main(String[] args) { 
     Test<Integer> a = new Test<Integer>(); 
     System.out.println(a.boo()); 
     a.setVar(new Integer(10)); 
     System.out.println(a.boo()); 
    } 

    public String boo() { 
     if (var == null) { 
      return "Don't know yet"; 
     } 
     return var.getClass().getSimpleName(); 
    } 

    public void setVar(T var) { 
     this.var = var; 
    } 

    public T getVar() { 
     return var; 
    } 
} 
+0

Considere el caso donde var se establece en una instancia de la clase X donde X se extiende T. boo() imprimirá X en lugar de T. – jackrabbit

12

No puede. La información se elimina del código en tiempo de compilación, un proceso que se conoce como borrado de tipo. Para obtener más información, consulte aquí: Type Erasure

editar: lo siento, mal, la información no se carga en tiempo de ejecución.

+1

Bueno, no es específicamente cierto, está en el archivo de clase como atributos de clase o método. Simplemente no está cargado en la memoria en tiempo de ejecución. – MeBigFatGuy

+0

@MeBigFatGuy: ¡gracias! Permítanme corregir lo que dije antes. –

3

En el caso de su situación, no puede. Sin embargo, es posible que pueda utilizar tokens de tipo Super para este tipo de cosas: http://gafter.blogspot.com/2006/12/super-type-tokens.html

Una implementación de ejemplo de esto es la clase TypeReference de la biblioteca de procesamiento Jackson json.

Esto es algo avanzado y probablemente más de lo que quería saber ;-)

4

Como otros han explicado, no se puede hacerlo de esa manera, pero esto es como se consigue normalmente en Java.

public class MyClass<T> { 
    public void method(Class<T> clazz) { 
     // something 

     System.out.println(clazz.getName()); 

     // something 
    } 
} 

y utilizar de esta manera

new MyClass<String>().method(String.class); 
0

notar que los enfoques depender de 'getClass()' en una instancia recibida con un tipo genérico obtendrá el tipo real de ese objeto, que no es necesariamente el tipo genérico - que sería el tipo por el cual el el llamador conocía la instancia.

Por ejemplo, considere el caso en que la persona que llama maneja un objeto por una interfaz; al pasar a constructos genéricos, el tipo genérico será la interfaz, no la clase real de la instancia.

Considere el ejemplo siguiente clase de "par", que permite que dos referencias a objetos que se devuelven a través de un POJO:

public class Pair<U,V> 
{ 
    public final U first; 
    public final V second; 
    public static <U,V> Pair<U,V> of (U first, V second) 
    { 
     return new Pair<U,V> (first, second); 
    } 
    protected Pair (U first, V second) 
    { 
     this.first = first; 
     this.second = second; 
    } 
} 

Estábamos teniendo en cuenta cómo modificar la función de la fábrica 'Pair.of()' para volver una clase derivada del par comparable, si U y V eran ambos comparables. Sin embargo, aunque podemos decir si 'primero' y 'segundo' son comparables usando instanceof, no sabemos que 'U' y 'V' son comparables.

Para que esto funcione, el tipo exacto de par devuelto por Pair.de() debe depender de los tipos genéricos, no los tipos de argumentos reales.

Cuestiones relacionadas