2012-04-11 18 views
53

¿Cómo puedo hacer que este tipo de cosas funcionen? Puedo verificar si (obj instanceof List<?>) pero no si es (obj instanceof List<MyType>). ¿Hay alguna manera de hacer esto?cómo instanceof List <MyType>?

+1

Ver http://docs.oracle.com/javase/tutorial/java/generics/erasure.html –

+0

posible duplicado de [no se puede realizar instanceof comprobar contra parameteri zed tipo ArrayList ] (http://stackoverflow.com/questions/7335018/cannot-perform-instanceof-check-against-parameterized-type-arraylistfoo) –

Respuesta

35

Eso no es posible debido a la eliminación del tipo de datos en tiempo de compilación de los genéricos. Sólo es posible manera de hacer esto es escribir algún tipo de envoltorio que mantiene el tipo tiene la lista:

public class GenericList <T> extends ArrayList<T> 
{ 
    private Class<T> genericType; 

    public GenericList(Class<T> c) 
    { 
      this.genericType = c; 
    } 

    public Class<T> getGenericType() 
    { 
      return genericType; 
    } 
} 
+0

¿hay una forma alternativa de comprobarlo? –

+0

Gracias, creo que pasaré el tipo genérico a la función a la que llamo para verificar y verificar ambos elementos. –

8

Es probable que tenga que utilizar la reflexión para obtener los tipos de ellos para comprobar. para obtener el tipo de la lista: Get generic type of java.util.List

+1

Hasta donde yo sé, eso solo funciona para los campos, pero +1 por mencionarlo. –

16
if(!myList.isEmpty() && myList.get(0) instanceof MyType){ 
    // MyType object 
} 
+0

... y para una lista vacía? Reflexiones? – Gewure

+0

Yeap. Esa es la única opción disponible para la lista vacía. https://stackoverflow.com/questions/1942644/get-generic-type-of-java-util-list – Sathish

+1

Esta respuesta no es segura, porque incluso si el elemento 0 es un MyType, los otros elementos podrían ser de otro tipo . Por ejemplo, tal vez la lista fue declarada como ArrayList , luego se agregó un MyType y luego se agregó una cadena. –

0

Si usted está verificando si una referencia de un valor de la lista o mapa del objeto es una instancia de una colección, basta con crear una instancia de lista requerida y obtener su clase ...

Set<Object> setOfIntegers = new HashSet(Arrays.asList(2, 4, 5)); 
assetThat(setOfIntegers).instanceOf(new ArrayList<Integer>().getClass()); 

Set<Object> setOfStrings = new HashSet(Arrays.asList("my", "name", "is")); 
assetThat(setOfStrings).instanceOf(new ArrayList<String>().getClass()); 
+0

¿Cuál es el punto de su 'setOfIntegers' y' setOfStrings'? – DanielM

+0

@DanielM acaba de actualizar la muestra. ¡Debe estar usando esas referencias! ¡Gracias! –

0

Si esto no se puede envolver con los genéricos (@ respuesta de Martijn) es mejor pasarlo sin poner en la lista para evitar redundante iteración (chequear el tipo del primer elemento no garantiza nada). Podemos moldear cada elemento en el fragmento de código donde iteramos la lista.

Object attVal = jsonMap.get("attName"); 
List<Object> ls = new ArrayList<>(); 
if (attVal instanceof List) { 
    ls.addAll((List) attVal); 
} else { 
    ls.add(attVal); 
} 

// far, far away ;) 
for (Object item : ls) { 
    if (item instanceof String) { 
     System.out.println(item); 
    } else { 
     throw new RuntimeException("Wrong class ("+item .getClass()+") of "+item); 
    } 
} 
0

Se puede utilizar una fábrica falsa para incluir muchos métodos en lugar de utilizar instanceof:

public class Message1 implements YourInterface { 
    List<YourObject1> list; 
    Message1(List<YourObject1> l) { 
     list = l; 
    } 
} 

public class Message2 implements YourInterface { 
    List<YourObject2> list; 
    Message2(List<YourObject2> l) { 
     list = l; 
    } 
} 

public class FactoryMessage { 
    public static List<YourInterface> getMessage(List<YourObject1> list) { 
     return (List<YourInterface>) new Message1(list); 
    } 
    public static List<YourInterface> getMessage(List<YourObject2> list) { 
     return (List<YourInterface>) new Message2(list); 
    } 
} 
0

Esto podría ser utilizado si se desea comprobar que object es instancia de List<T>, que no está vacío:

if(object instanceof List){ 
    if(((List)object).size()>0 && (((List)object).get(0) instanceof MyObject)){ 
     // The object is of List<MyObject> and is not empty. Do something with it. 
    } 
}