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:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
Ensuite, vous pouvez utiliser isAssignableFrom pour vérifier le type.
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
Chaque fois que vous instanciez votre objet, vous devrez vous répéter:
new MyCollection<Apples>(Apples.class);
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:
protected abstract void abstractMethod(T element);
Vous pouvez l'utiliser comme ceci:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
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.
Class.isAssignableFrom
.