2012-04-11 14 views
53

Jak mogę sprawić, aby tego typu rzeczy działały? Mogę sprawdzić, czy jest to (obj instanceof List<?>), ale nie, jeśli (obj instanceof List<MyType>). Czy jest sposób, aby to zrobić?jak do instanceof List <MyType>?

+1

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

+0

możliwe duplikat [nie można wykonać instanceof sprawdzić przed parameteri zed type ArrayList ] (http://stackoverflow.com/questions/7335018/cannot-perform-instanceof-check-against-parameterized-type-arraylistfoo) –

Odpowiedz

35

Nie jest to możliwe, ponieważ typ danych wymazuje się podczas kompilacji generycznych. Jedynym możliwym sposobem osiągnięcia tego celu jest napisanie jakiegoś owijki, która posiada jaki typ posiada listy:

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 czy jest inny sposób na sprawdzenie? –

+0

Dzięki, myślę, że po prostu przekażę rodzajowy typ do funkcji, do której dzwonię, aby sprawdzić i sprawdzić oba elementy. –

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

... i dla pustej listy? Refleksje? – Gewure

+0

Yeap. To jedyna dostępna opcja dla pustej listy. https://stackoverflow.com/questions/1942644/get-generic-type-of-java-util-list – Sathish

+1

Ta odpowiedź nie jest bezpieczna, ponieważ nawet jeśli elementem 0 jest MyType, pozostałe elementy mogą być innymi typami . Na przykład, może lista została zadeklarowana jako ArrayList , następnie dodano MyType, a następnie dodano łańcuch. –

0

Jeśli sprawdzenie czy odwołanie z listy lub mapy wartości obiekt jest instancją Collection, wystarczy utworzyć instancję wymaganego listy i uzyskać jego klasa ...

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

Jaki jest sens "setOfIntegers" i "setOfStrings"? – DanielM

+0

@DanielM właśnie zaktualizował próbkę. Musi używać tych odniesień! Dzięki! –

0

Jeśli to nie może być owinięty generycznych (@ odpowiedź Martijn jest) lepiej przekazać go bez odlewania, aby uniknąć redundantny listy iteracji (sprawdzanie typu pierwszego elementu gwarantuje niczego). Możemy rzutować każdy element w kodzie, w którym wykonujemy iterację listy.

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

Można użyć fałszywego fabryki obejmuje wiele metod Zamiast używać 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

To może być stosowane, jeżeli chcesz sprawdzić, object jest instancją List<T>, która nie jest pusta:

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