2011-04-20 10 views
51

¿Hay alguna manera de determinar si un objeto es una instancia de un tipo genérico?Prueba si el objeto es instancia de un tipo de parámetro

public <T> test(Object obj) { 
    if (obj instanceof T) { 
     ... 
    } 
} 

Eso claramente no funciona. ¿Hay una alternativa? Me gustaría utilizar la reflexión de Java para crear una instancia de una clase y luego verificar para asegurarse de que sea de tipo genérico T.

Respuesta

80

La única manera de hacer esta comprobación es si usted tiene el objeto que representa el tipo Class:

Class<T> type; //maybe passed into the method 
if (type.isInstance(obj)) { 
    //... 
} 
+0

Si no desea obtener 'type' como parámetro de método, tal vez quiera inicializarlo:' Class type = ((T) new Object()). GetClass(); ' – JordiVilaplana

+4

@JordiVilaplana Eso no es correcto , te dará java.lang.Object como clase. Mira esto: http://ideone.com/bxt9Jq –

+0

Uso: = ( clase) ((ParameterizedType) getClass() getGenericSuperclass()). GetActualTypeArguments clase ' tipo() [0];' –

3

Tendría más sentido poner la restricción en donde se usa el tipo T para parametrizar el tipo Class. Cuando pase el tipo, en lugar de usar algo como Class<?>, debe usar Class<? extends T>.

+1

Si usted quiere saber el tipo exacto de T en tiempo de ejecución, es importante exigir que la persona que llama pasar de una clase , no una clase . Por ejemplo, el código de Puce no se compilaría con la clase . –

1

esto sólo funcionará (en parte) si tiene un objeto de tipo T. A continuación, se puede obtener la clase de ese objeto, vea java.lang.Class<T> y encuentre si es lo mismo que el objeto en cuestión.

Pero tenga en cuenta que esto va en contra de la razón por la que tenemos genéricos: el uso de un tipo genérico es una manera de decir que no le importa qué tipo es realmente (hasta límites superiores e inferiores que pueden especificarse).

+0

La clase . devuelto desde una llamada .getClass() en una instancia T no nula no garantiza que sea una Clase . Lo mejor que puede garantizar es que es una clase . –

12

Extender la muestra de Mark Peters, frecuencia con que desea hacer algo como:

Class<T> type; //maybe passed to the method 
if (type.isInstance(obj)) { 
    T t = type.cast(obj); 
    // ... 
} 
6

Usted podría intentar esto,

// Cast your object to the generic type. 
T data = null; 
try { 
    data = (T) obj; 
} catch (ClassCastException cce) { 
    // Log the error. 
} 

// Check if the cast completed successfully. 
if(data != null) { 
    // whatever.... 
} 
+1

** ¡Esto no funciona! ** El reparto tiene éxito para ** todos los tipos **. Por eso da una advertencia de compilación de "rechazo no verificado". – Lii

1

Si no desea pasar el tipo de clase como un parámetro como lo menciona Mark Peters, puede usar el siguiente código. Felicitaciones a David O'Meara.

Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) 
        .getActualTypeArguments()[0]; 
    if (type.isInstance(obj)) { 
     ... 
    } 
Cuestiones relacionadas