Frage

Nehmen wir an, ich habe die folgende Klasse:

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

Wie würde ich das überprüfen? o ist die gleiche Klasse wie E?

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

Ich kann die Methodensignatur von nicht ändern (Object o) da ich eine Superklasse überschreibe und daher meine Methodensignatur nicht auswählen kann.

Ich würde auch lieber nicht den Weg gehen, eine Umwandlung zu versuchen und dann die resultierende Ausnahme abzufangen, wenn sie fehlschlägt.

War es hilfreich?

Lösung

Ein Beispiel für Test hat keine Informationen darüber, was E ist zur Laufzeit.Sie müssen also a bestehen Class<E> an den Konstrukteur von 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;
    }
}

Wenn Sie eine „instanceof“-Beziehung wünschen, verwenden Sie Class.isAssignableFrom anstatt der Class Vergleich.Notiz, E Aus dem gleichen Grund muss es sich um einen nicht generischen Typ handeln Test braucht das Class Objekt.

Beispiele für die Java-API finden Sie unter java.util.Collections.checkedSet und ähnliches.

Andere Tipps

Die Methode, die ich immer verwendet habe, ist unten.Es ist mühsam und ein bisschen hässlich, aber ich habe kein besseres gefunden.Sie müssen den Klassentyp bei der Erstellung weitergeben, da beim Kompilieren von Generics Klasseninformationen verloren gehen.

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);
    }
}

Ich konnte es nur so zum Laufen bringen:

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);  
    }
}

Ich habe gerade versucht, das Gleiche zu tun, und ein netter Trick, der mir gerade aufgefallen ist, ist, dass man einen Cast ausprobieren kann, und wenn der Cast fehlschlägt, wird ClassCastException ausgelöst.Sie können das fangen und tun, was auch immer.

Ihre Methode sameClassAs sollte also wie folgt aussehen:

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;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top