web-dev-qa-db-fra.com

pourquoi instanceof ne fonctionne pas avec Generic?

Duplicata possible:
Java: Instance de et génériques

J'essaie d'écrire une fonction qui jette une liste générique dans un type spécifique List. Trouvez le code ci-dessous

public <T>List<T> castCollection(List srcList, Class<T> clas){
    List<T> list =new ArrayList<T>();
    for (Object obj : srcList) {
       if(obj instanceof T){
            ...
       }
    }
    return list;
}

Mais obj instanceof T montrant une erreur de compilation -

Impossible d'effectuer une vérification instanceof par rapport au paramètre de type T. Utilisez plutôt son objet d'effacement> à la place, car d'autres informations de type génériques seront effacées lors de l'exécution.

une clarification ou un moyen d'obtenir le résultat souhaité?

Merci d'avance. :)

20

Vous ne pouvez pas le faire de cette façon. Heureusement, vous avez déjà un argument Class<T> Alors faites plutôt

myClass.isAssignableFrom(obj.getClass())

Cela retournera vrai si obj est de classe myClass ou de sous-classe.

Comme l'a souligné @ILMTitan (merci), vous devrez vérifier obj == null Pour éviter une NullPointerException potentielle, ou utiliser myClass.isInstance(obj) à la place. Soit ce dont vous avez besoin.

37
Jim Garrison

Réponse courte: car un paramètre de type dans Java est quelque chose que le compilateur utilise pour garantir la sécurité des types.

Au moment de l'exécution, les informations de type sur les types génériques sont ignorées en raison de l'effacement de type mais instanceof est un contrôle d'exécution qui nécessite un type concret (pas une variable de type) pour fonctionner.

8
Jack

T est un type paramétré et existe à des fins de compilation. Il n'existe pas à l'exécution en raison de l'effacement de type.

Donc, obj instanceof T n'est pas légal.

4
fge

Parce que Java utilise l'effacement, les types génériques ne peuvent pas être utilisés pour vérifier.

Pour obtenir le résultat souhaité, utilisez Class.isInstance().

4
ILMTitan

Les types génériques seront effacés après la compilation (les génériques sont pour la sécurité du type de compilation) et seront remplacés par le type le plus applicable après la compilation.

Si vous voulez faire cette compilation, remplacez T par un type de béton, exemple

obj instance String
2
kosa