2011-10-21 26 views
5

decir que tengo una clase como la siguienteJava reflexión: Obtener el tipo concreto de interfaz genérica implementado

public class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
... 
} 

¿Es posible obtener el AtomEntry.class objeto de clase de la clase de objeto de AtomEntryHandler.class?

No pensé que fuera posible debido al borrado, pero un amigo dijo que sí.

+0

¿Dijo tu amigo cómo? –

+2

no, de ahí la pregunta :-D – ekj

+0

¿La respuesta de Alex Gitelman funciona para usted? –

Respuesta

4

No pude encontrar una forma de determinar el parámetro de tipo de base en caso de implementación de la interfaz (lo que no significa que no haya ninguna). Pero esto es lo más cercano a eso.

import java.lang.reflect.*; 
public class Foo { 
    static class Bar<T> { 
    } 
    static class SubBar extends Bar<Integer> { 
    } 

    public static void main(String argv[]) { 
    ParameterizedType pt = (ParameterizedType)SubBar.class.getGenericSuperclass(); 
    Type[] t = pt.getActualTypeArguments(); 
    for (int i=0;i<t.length;i++) { 
     System.out.println(t[i]); 
    } 
    } 
} 

Resultado: class java.lang.Integer

8

Usted puede obtener el tipo genérico para ambas interfaces y subclases directas, pero sólo para la aplicación concreta. Por ejemplo, si tiene una instancia de List<T>, no tiene forma de saber para qué se ha parametrizado debido a la eliminación de tipo. Si la definición de clase incluye tipos parametrizados que se conocen en tiempo de compilación (por ejemplo, class StringList extends List<String>), entonces puede recuperar esa información.

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0]; 
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0]; 
+2

Leí acerca de la interfaz en doc, pero si la clase implementa la interfaz parametrizada como en cuestión (y no extiende ninguna clase explícitamente), obtendrá 'java.lang.Object' y lanzará una excepción al convertir a' ParameterizedType'. –

+0

Si llama a 'getGenericSuperclass()' y no extiende explícitamente nada o extiende clases no genéricas, eso es cierto, pero si llama a 'getGenericInterfaces()' entonces la jerarquía de clases no importa porque solo se trata de interfaces. –

1

Si por casualidad usted conoce ConsumingHandler es la única interfaz AtomEntryHandler implementa y por casualidad usted conoce sólo se necesita un argumento de tipo, se puede hacer esto:

interface ConsumingHandler<T> {} 

class AtomEntry {} 

class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
    public static void main(String[] args) 
    { 
     Type[] interfaces = AtomEntryHandler.class.getGenericInterfaces(); 
     ParameterizedType firstInterface = (ParameterizedType) interfaces[0]; 
     Class c = (Class) firstInterface.getActualTypeArguments()[0]; 
     System.out.println(c.getName()); // prints "AtomEntry" 
    } 
} 

De lo contrario, puede hurgar en getGenericInterfaces() y su actualTypeArguments hasta que encuentre algo que se parece a lo que está buscando.

Pero si necesita hacer esto en código real, o bien algo probablemente salió mal en su diseño, o está escribiendo una biblioteca de objetos falsos de genio loco y no debería necesitar que respondamos a estas preguntas.

+0

Sí, tuve un juego con eso, y solo hace que el código sea más complicado de lo necesario. Habría evitado alguna duplicación si fuera simple. – ekj

Cuestiones relacionadas