2012-04-11 8 views
53

Come posso far funzionare questo tipo di cose? Posso verificare se (obj instanceof List<?>) ma non se (obj instanceof List<MyType>). C'è un modo in cui questo può essere fatto?come esempio dell'elenco <MyType>?

+1

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

+0

possibile duplicato del [Impossibile eseguire instanceof controllare contro parameteri tipo zed ArrayList ] (http://stackoverflow.com/questions/7335018/cannot-perform-instanceof-check-against-parameterized-type-arraylistfoo) –

risposta

35

Ciò non è possibile perché il tipo di dati viene cancellato in fase di compilazione dei generici. Solo modo possibile per farlo è quello di scrivere una sorta di involucro che contiene il tipo lista contiene:

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

ok c'è un modo alternativo per controllarlo? –

+0

Grazie, penso che passerò il tipo generico alla funzione che sto chiamando per controllare e controllare entrambi gli elementi. –

8

Probabilmente è necessario utilizzare la reflection per ottenere i tipi di loro per controllare. per ottenere il tipo di lista: Get generic type of java.util.List

+1

Per quanto ne so, funziona solo per i campi, ma +1 per menzionarlo. –

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

... e per una lista vuota? Riflessi? – Gewure

+0

Yeap. Questa è l'unica opzione disponibile per la lista vuota. https://stackoverflow.com/questions/1942644/get-generic-type-of-java-util-list – Sathish

+1

Questa risposta non è sicura, perché anche se l'elemento 0 è un MyType, gli altri elementi potrebbero essere altri tipi . Ad esempio, forse l'elenco è stato dichiarato come ArrayList , quindi è stato aggiunto un MyType e quindi è stata aggiunta una stringa. –

0

Se si sta verificando se il riferimento di un valore di lista o mappa di oggetto è un'istanza di una collezione, basta creare un'istanza di elenco richiesto e ottenere la sua classe ...

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

Qual è il punto di 'setOfIntegers' e' setOfStrings'? – DanielM

+0

@DanielM ha appena aggiornato il campione. Deve usare quei riferimenti! Grazie! –

0

Se questo non può essere avvolto con i generici (@ risposta di Martijn) è meglio passare senza colata evitare lista ridondante iterazione (controllare il tipo del primo elemento garantisce nulla). Possiamo castare ogni elemento nel pezzo di codice dove iteriamo l'elenco.

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

È possibile utilizzare una fabbrica falso per includere molti metodi, invece di utilizzare 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

Questo potrebbe essere utilizzato se si desidera verificare che object è istanza di List<T>, che non è vuoto:

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. 
    } 
}