Avant de parcourir ma structure de données générique pour l'index d'une valeur, j'aimerais voir s'il s'agit même d'une instance du type this
lequel a été paramétrée.
Mais Eclipse se plaint quand je fais cela:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
Voici le message d'erreur:
Impossible d'effectuer une vérification instanceof par rapport au paramètre de type E. Utilisez à la place son objet d'effacement car les informations de type générique seront effacées à l'exécution
Quelle est la meilleure façon de procéder?
la source
Class.isAssignableFrom
.Deux options pour la vérification du type d'exécution avec des génériques:
Option 1 - corrompez votre constructeur
Supposons que vous surchargez indexOf (...), et que vous souhaitez vérifier le type uniquement pour les performances, pour vous éviter d'itérer toute la collection.
Créez un constructeur sale comme celui-ci:
Ensuite, vous pouvez utiliser isAssignableFrom pour vérifier le type.
Chaque fois que vous instanciez votre objet, vous devrez vous répéter:
Vous pourriez décider que cela n'en vaut pas la peine. Dans l'implémentation de ArrayList.indexOf (...) , ils ne vérifient pas que le type correspond.
Option 2 - Laissez-le échouer
Si vous avez besoin d'utiliser une méthode abstraite qui nécessite votre type inconnu, alors tout ce que vous voulez vraiment, c'est que le compilateur arrête de pleurer sur instanceof . Si vous avez une méthode comme celle-ci:
Vous pouvez l'utiliser comme ceci:
Vous transtypez l'objet en T (votre type générique), juste pour tromper le compilateur. Votre distribution ne fait rien au moment de l'exécution , mais vous obtiendrez toujours une ClassCastException lorsque vous essayez de transmettre le mauvais type d'objet dans votre méthode abstraite.
REMARQUE 1: si vous effectuez des transtypages non vérifiés supplémentaires dans votre méthode abstraite, vos ClassCastExceptions seront interceptées ici. Cela pourrait être bon ou mauvais, alors réfléchissez-y.
REMARQUE 2: vous obtenez une vérification nulle gratuite lorsque vous utilisez instanceof . Puisque vous ne pouvez pas l'utiliser, vous devrez peut-être vérifier la valeur null à mains nues.
la source
Ancien message, mais un moyen simple de faire une vérification générique d'instance.
la source
Si votre classe étend une classe avec un paramètre générique, vous pouvez également l'obtenir au moment de l'exécution via la réflexion, puis l'utiliser pour la comparaison, c'est-à-dire
Dans le cas ci-dessus, à l'exécution, vous obtiendrez String.class de getParameterizedClass (), et il se met en cache afin que vous n'obteniez aucune surcharge de réflexion lors de plusieurs vérifications. Notez que vous pouvez obtenir les autres types paramétrés par index à partir de la méthode ParameterizedType.getActualTypeArguments ().
la source
J'ai eu le même problème et voici ma solution (très humble, @george: cette fois compiler ET travailler ...).
Mon problème était à l'intérieur d'une classe abstraite qui implémente Observer. La méthode Observable déclenche la mise à jour (...) avec la classe Object qui peut être n'importe quel type d'Object.
Je veux uniquement gérer des objets de type T
La solution est de passer la classe au constructeur afin de pouvoir comparer les types à l'exécution.
Pour l'implémentation, nous devons juste passer la classe au constructeur
la source
Ou vous pourriez attraper une tentative ratée de lancer dans E par exemple.
la source
Techniquement, vous ne devriez pas avoir à le faire, c'est le but des génériques, vous pouvez donc vérifier le type de compilation:
mais alors le @Override peut être un problème si vous avez une hiérarchie de classes. Sinon, voyez la réponse de Yishai.
la source
Le type d'exécution de l'objet est une condition relativement arbitraire sur laquelle filtrer. Je suggère de garder cette saleté loin de votre collection. Ceci est simplement réalisé en ayant votre délégué de collection à un filtre passé dans une construction.
la source
Comparator
ou similaire.)