2 Stimmen

Erhalt der originalen Java-Klasse beim Verwenden von instanceof und Casting

Zunächst einmal, für alle da draußen, die den instanceof-Operator verabscheuen, verachten und verabscheuen, verstehe ich Ihre Bedenken damit, aber ich bin gezwungen, es zu verwenden. Das liegt daran, dass ich nicht die Autorität habe, die Art und Weise vollständig umzustrukturieren, wie ein anderes Entwicklungsteam ein Projekt aufgesetzt hat, also es sei denn, ich übersehe hier etwas, sehe ich einfach keinen Weg, es zu umgehen.

Ich habe ein Java POJO, das nicht geändert werden kann und es Ihnen ermöglicht, eine Exception als eine seiner Eigenschaften festzulegen:

public class Message {
    private Exception exception;

    public void setException(Exception exc) {
        this.exception = exc;
    }
}

Nochmals, ich kann diese Message-Klasse nicht ändern.

Ich schreibe eine Fehlerbehandlungsmethode, die eine Instanz von MessageContainer übergeben bekommt, und ich benötige eine Logik, um verschiedene Dinge zu tun, abhängig davon, welcher Typ von Ausnahme auf der Message des Containers eingestellt wurde:

public class ErrorHandler {
    public void handle(MessageContainer container) {
        Message msg = container.getMessage();
        Exception exc = msg.getException();

        if(exc instanceof FizzException)
            System.out.println("Tu x");
        else if(exc instanceof BuzzException)
            System.out.println("Tu y");
        else
            System.out.println("Tu z");
    }
}

Nochmals, ich kann die Tatsache nicht ändern, dass ErrorHandler#handle eine Instanz von MessageContainer übergeben bekommt und nicht eine injectable Message-Instanz.

Also, auch wenn ich instanceof wirklich nicht mag, sehe ich keinen anderen Weg, um diese Logik zu erreichen (aber machen Sie gerne Vorschläge... solange sie keine Änderungen an Message, MessageContainer oder der Methode handle(MessageContainer) beinhalten!).

Aber selbst wenn ich instanceof verwende, wie funktioniert dieser Code überhaupt? Sobald Sie die Exception aus der Message herausziehen, glaube ich nicht, dass eines der instanceofs ausgelöst wird, weil es als Exception gecastet ist, ohne die Möglichkeit zu erkennen, ob es sich um BuzzException, FizzException usw. handelt. Was sind meine Möglichkeiten hier? Vielen Dank im Voraus.

3voto

Bastien Jansen Punkte 8636

Dieser Code wird wie erwartet funktionieren. Während der Laufzeit vergleichen instanceof-Anweisungen den tatsächlichen Typ von exc und nehmen nicht einfach an, dass dies nur eine Ausnahme ist. Wenn die einzige Anweisung, die funktioniert hat, exc instanceof Exception war, wäre instanceof völlig wertlos :)

Eine andere Lösung (die ich vermeiden würde zu verwenden) wäre, die vollständigen Klassennamen zu vergleichen:

String fqcn = exc.getClass().getName();

if (fqcn.equals("com.foo.FizzException") {
    // usw.
}

1voto

drone.ah Punkte 1136

Der Umwandlung in eine Ausnahme auf

Exception exc = msg.getException();

löscht nicht den Ausnahme-Runtime-Typ. Es hat sie nur in einen Basistyp umgewandelt. Das instanceof wird immer noch funktionieren. Wenn Ihre FizzException jedoch von BuzzException abgeleitet ist, müssen Sie die instanceof-Überprüfungen in umgekehrter Reihenfolge durchführen. d.h. überprüfen Sie zuerst den am weitesten abgeleiteten Typ.

Andernfalls wird es in die Basisklassenprüfklausel anstelle der abgeleiteten übergehen.

1voto

Hot Licks Punkte 46043

Es ist nicht klar, was du willst. Wenn die Ausnahmen alle "gegeben" sind und du ihre Implementierungen nicht ändern kannst, kannst du exception.getClass().getName() verwenden, um den Klassennamen zu erhalten und möglicherweise in einer Tabelle oder woanders nachschauen, um deine Vorgehensweise zu wählen.

Wenn du viele der Ausnahmenimplementierungen ändern kannst, lass sie alle eine Schnittstelle implementieren, die eine "functionality()" Methode oder ähnliches bereitstellt. Wenn ein bestimmtes Exception-Objekt instanceof MyFunctionalityInterface ist, dann wandle es in MyFunctionalityInterface um und rufe functionality() auf, um die Informationen zu erhalten, die du benötigst, um deine Aktionen zu steuern. Verwende dann instanceof oder getClass().getName(), um die Exception-Klassen zu verwalten, die du nicht ändern kannst.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X