2010-11-11 10 views
7

tengo la función a continuación:Obtener tipo de tipo genérico dentro de una lista en Java


    public <T> void putList(String key, List<T> lst){ 
      if (T instanceof String) { 
      // Do something  
      } 
      if (T instanceof Integer) { 
      // Do something 
      } 
    } 

Dentro de esta función, quiero saber si <T> es cadena o un entero por lo que me pregunto si hay una manera para descubrir su tipo? Utilicé el código anterior pero generó el error

Gracias de antemano.

+0

el operador instanceof no funciona en T. Vas a tener que conseguir realmente un elemento de la lista, como LST. get (0) instanceof String –

Respuesta

8

No puede encontrar el tipo de T ya que la información del tipo se borra. Consulte this para obtener más detalles. Pero si la lista no está vacía, se puede obtener un elemento de la lista y puede averiguar usando instanceof y if else

+4

supongamos que obtiene un elemento y es nulo, entonces instanceof no lo ayudará – newacct

-1

Utilice el operador instanceof.

Dicho esto, las operaciones genéricas deben ser, bueno, genéricas, así que tenga cuidado de cambiar el comportamiento según el tipo.

+0

el operador instanceof no funcionará en parámetros de tipo genérico como T –

+0

Puede hacer lst.get [0] instaceof String ... – PaulJWilliams

+0

@Visage ese es un buen [email protected] Kantamneni dijo lo mismo en su respuesta, siempre y cuando la lista no esté vacía –

9

No es posible en Java debido a erasure. Lo que hace la mayoría de la gente es agregar un token de tipo. Ejemplo:

public <T> void putList(String key, List<T> list, Class<T> listElementType) { 
} 

Hay ciertas situaciones donde la reflexión se puede conseguir en el parámetro de tipo, pero es para casos en los que usted ha pre-establecido el parámetro de tipo. Por ejemplo:

public class MyList extends List<String> { 
    private List<String> myField; 
} 

En ambos de los casos reflexión puede determinar la lista es de tipo String, pero la reflexión no puede determinar que para su caso. Tendría que usar un enfoque diferente como un token de tipo.

-1
Type genericType = lst.getType(); 

if(genericType instanceof ParameterizedType){ 
    ParameterizedType aType = (ParameterizedType) genericType; 
    Type[] fieldArgTypes = aType.getActualTypeArguments(); 
    for(Type fieldArgType : fieldArgTypes){ 
     Class fieldArgClass = (Class) fieldArgType; 
     System.out.println("fieldArgClass = " + fieldArgClass); 
    } 
} 
+0

Hola, Neil. gracias por su respuesta, pero no pude encontrar el método getType() de la lista lst –

+0

Eso es porque no existe tal cosa. – DJClayworth

1

No es posible determinar esto debido a erasure, lo que significa que el parámetro no se almacena en el código. Sin embargo usted puede pasar un parámetro adicional que especifica de qué tipo es la lista es:

public <T> void putList(String key, List<T> lst, Class<T> listElementType) { 

}

o se puede determinar el tipo de cada elemento en tiempo de ejecución:

public <T> void putList(String key, List<T> lst){ 
    for (Object elem:lst) { 
     if (elem instanceof String) { 
     // Do something  
     } 
     if (elem instanceof Integer) { 
     // Do something 
     } 
    } 
} 
1

Los genéricos son llamados " borrados "porque existen solo en tiempo de compilación y son eliminados por el compilador. Entonces, no hay forma de determinar el tipo genérico de colección. La única forma de hacerlo para las listas no vacías es tomar el primer elemento y determinar su tipo.

Esta es casi la misma solución sugerida por DJClayworth, pero creo que no es necesario verificar cada elemento de la lista. Si está seguro de que la lista se crea con genéricos (nueva ArrayList() o nueva LinkedList() etc.), se garantiza que todos sus elementos serán del mismo tipo.

0

Si quieres función del objeto de gestión, que puede hacer:

public <T> void putList(String key, List<T> lst){ 
for(T object : lst) 
{ 
    if(object instanceof String) { 
     doSomething(((String)object).doForString()) 
    } 
    if(object instanceof Integer) { 
     doSomething(((Integer)object).doForInteger()) 
    } 
} 
Cuestiones relacionadas