2010-11-11 7 views
7

J'ai la fonction ci-dessous:Obtenir type de type générique dans une liste en Java


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

Dans cette fonction, je veux savoir si <T> est une chaîne ou un entier donc je me demande s'il y a un moyen pour découvrir son type? J'ai utilisé le code ci-dessus, mais il a généré une erreur

Merci d'avance.

+0

l'opérateur instanceof ne fonctionne pas sur T. Vous devez obtenir effectivement un élément de la liste, comme LST. get (0) instanceof Chaîne –

Répondre

8

Vous ne pouvez pas trouver le type de T lorsque les informations de type sont effacées. Vérifiez this pour plus de détails. Mais si la liste n'est pas vide, vous pouvez obtenir un élément de la liste et trouver en utilisant instanceof et if else

+4

Supposons que vous obteniez un élément et qu'il soit nul, alors instanceof ne vous aidera pas – newacct

-1

Utilisez l'opérateur instanceof. Cela dit, les opérations génériques devraient être, bien, génériques, alors méfiez-vous du changement de comportement en fonction du type.

+0

l'opérateur instanceof ne travaillera pas sur les paramètres de type générique comme T –

+0

Vous pourriez faire lst.get [0] instaceof String ... – PaulJWilliams

+0

@Visage c'est un bon [email protected] Kantamneni dit la même chose dans sa réponse, tant que la liste n'est pas vide –

9

Ce n'est pas possible en Java en raison de erasure. Ce que font la plupart des gens est d'ajouter un jeton de type. Exemple:

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

Il y a certaines situations où la réflexion peut obtenir au paramètre de type, mais il est des cas où vous avez le paramètre de type prédéfini. Par exemple:

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

Dans ces deux cas, la réflexion peut déterminer la liste est de type String, mais la réflexion ne peut pas déterminer pour votre cas. Vous devrez utiliser une approche différente comme un jeton de type.

-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

Salut Neil. merci pour votre réponse, mais je ne pouvais pas trouver la méthode getType() de lst Liste –

+0

C'est parce qu'il n'y a pas une telle chose. – DJClayworth

1

Il est impossible de déterminer ce dû à erasure, ce qui signifie que le paramètre ne sont pas stockées dans le code. Cependant, vous pouvez passer un paramètre supplémentaire spécifiant quel type de la liste est la suivante:

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

}

ou vous pouvez déterminer le type de chaque élément lors de l'exécution:

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

Generics sont appelés " effacements "car ils n'existent qu'à la compilation et sont supprimés par le compilateur. Donc, il n'y a aucun moyen de déterminer le type de collection générique. La seule façon de le faire pour les listes non vides est de prendre le premier élément et de déterminer son type.

C'est presque la même solution que celle suggérée par DJClayworth, mais je pense qu'il n'est pas nécessaire de vérifier chaque élément de la liste. Si vous êtes sûr que la liste est créée avec des génériques (new ArrayList() ou new LinkedList() etc), tous ses éléments sont garantis être du même type.

0

Si vous souhaitez exécuter la fonction de l'objet, vous pouvez faire:

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()) 
    } 
} 
Questions connexes