Question

Disons que j'ai la classe suivante :

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

Comment pourrais-je vérifier cela o est la même classe que E?

Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;

Je ne peux pas changer la signature de la méthode (Object o) car je remplace une superclasse et je ne peux donc pas choisir ma signature de méthode.

Je préférerais également ne pas tenter une conversion, puis détecter l'exception qui en résulte si elle échoue.

Était-ce utile?

La solution

Un exemple de Test n'a aucune information sur ce que E est au moment de l'exécution.Il faut donc passer un Class<E> au constructeur de Test.

public class Test<E> {
    private final Class<E> clazz;
    public Test(Class<E> clazz) {
        if (clazz == null) {
            throw new NullPointerException();
        }
        this.clazz = clazz;
    }
    // To make things easier on clients:
    public static <T> Test<T> create(Class<T> clazz) {
        return new Test<T>(clazz);
    }
    public boolean sameClassAs(Object o) {
        return o != null && o.getClass() == clazz;
    }
}

Si vous souhaitez une relation "instanceof", utilisez Class.isAssignableFrom à la place du Class comparaison.Note, E devra être un type non générique, pour la même raison Test a besoin du Class objet.

Pour des exemples dans l'API Java, voir java.util.Collections.checkedSet et similaire.

Autres conseils

La méthode que j’ai toujours utilisée est ci-dessous.C'est pénible et un peu moche, mais je n'en ai pas trouvé de meilleur.Vous devez transmettre le type de classe lors de la construction, car lorsque les génériques sont compilés, les informations de classe sont perdues.

public class Test<E> {
    private Class<E> clazz;
    public Test(Class<E> clazz) {
       this.clazz = clazz;
    }
    public boolean sameClassAs(Object o) {
        return this.clazz.isInstance(o);
    }
}

Je ne pouvais que le faire fonctionner comme ceci :

public class Test<E> {  

    private E e;  

    public void setE(E e) {  
        this.e = e;  
    }

    public boolean sameClassAs(Object o) {  

        return (o.getClass().equals(e.getClass()));  
    }

    public boolean sameClassAs2(Object o) {  
        return e.getClass().isInstance(o);  
    }
}

J'essayais juste de faire la même chose, et une astuce intéressante que je viens de réaliser est que vous pouvez essayer un casting, et si le casting échoue, ClassCastException sera levée.Vous pouvez l'attraper et faire n'importe quoi.

donc votre méthode sameClassAs devrait ressembler à :

public boolean sameClassAs(Object o) {
    boolean same = false;
    try {
        E t = (E)o;
        same = true;
    } catch (ClassCastException e) {
        // same is false, nothing else to do
    } finally {
        return same;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top