Ist es in Java möglich, zwei Ausnahmen im selben Catch-Block abzufangen? [duplicate]

Lesezeit: 3 Minuten

Benutzer-Avatar
Benutzer710818

Ich muss zwei Ausnahmen abfangen, weil sie die gleiche Behandlungslogik erfordern. Ich möchte so etwas tun:

catch (Exception e, ExtendsRuntimeException re) {
    // common logic to handle both exceptions
}

Ist es möglich, das Duplizieren des Handler-Codes in jedem Catch-Block zu vermeiden?

Benutzer-Avatar
Stefan C

Java 7 und höher

Fangen mit mehreren Ausnahmen werden ab Java 7 unterstützt.

Die Syntax lautet:

try {
     // stuff
} catch (Exception1 | Exception2 ex) {
     // Handle both exceptions
}

Der statische Typ von ex ist der spezialisierteste gemeinsame Supertyp der aufgeführten Ausnahmen. Es gibt ein nettes Feature, wenn Sie erneut werfen ex in catch weiß der Compiler, dass nur eine der aufgelisteten Ausnahmen ausgelöst werden kann.


Java 6 und früher

Vor Java 7 gab es Möglichkeiten, dieses Problem zu handhaben, aber sie sind in der Regel unelegant und weisen Einschränkungen auf.

Ansatz Nr. 1

try {
     // stuff
} catch (Exception1 ex) {
     handleException(ex);
} catch (Exception2 ex) {
     handleException(ex);
}

public void handleException(SuperException ex) {
     // handle exception here
}

Dies wird chaotisch, wenn der Ausnahmehandler auf lokale Variablen zugreifen muss, die vor deklariert wurden try. Und wenn die Handler-Methode die Ausnahme erneut auslösen muss (und sie überprüft wird), treten ernsthafte Probleme mit der Signatur auf. Speziell, handleException muss als Werfen deklariert werden SuperException … was möglicherweise bedeutet, dass Sie die Signatur der einschließenden Methode ändern müssen und so weiter.

Ansatz Nr. 2

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     } else {
         throw ex;
     }
}

Wieder einmal haben wir ein potenzielles Problem mit Signaturen.

Ansatz Nr. 3

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     }
}

Lässt man die aus else Teil (z. B. weil es keine anderen Subtypen von gibt SuperException im Moment) wird der Code zerbrechlicher. Wenn die Ausnahmehierarchie neu organisiert wird, wird dieser Handler ohne ein else kann Ausnahmen stillschweigend essen!

  • Wenn dies der Fall ist, wie behandelt der resultierende catch-Block Funktionen, die für einen bestimmten Ausnahmetyp eindeutig sind? Zum Beispiel ex.functionFromExceptionType2() vs ex.functionFromExceptionType1()

    – Pfirsiche491

    26. Juni 2012 um 19:27 Uhr

  • @ Peaches491 (1) die überwiegende Mehrheit der Ausnahmen hat genau die gleichen Methoden; (2) wenn Sie ein anderes Verhalten wünschen Type1 und Type2 dann können Sie dieses Konstrukt nicht verwenden.

    – Erinnerung

    26. Juni 2012 um 19:32 Uhr

  • Das habe ich mir schon gedacht. Ich dachte nur, ich würde fragen, um sicherzugehen

    – Pfirsiche491

    26. Juni 2012 um 19:34 Uhr

  • @emory Ich könnte mich irren, aber Ausnahmen sind Objekte. Also kannst du die nicht verwenden instanceof Funktion, um Ihr Ausnahmeobjekt zu sehen, ist innerhalb der catch-Anweisung von dem einen oder anderen Typ? Sie könnten also abfangen, gemeinsamen Code ausführen und dann if-Blöcke mit haben instanceof um den Code zu tun, der anders wäre.

    – Sephallia

    26. Juni 2012 um 21:25 Uhr


  • @Sephallia Du hast Recht. Es scheint rückwärts zu sein, aber Sie könnten Casting innerhalb der catch-Anweisung verwenden.

    – Erinnerung

    26. Juni 2012 um 22:18 Uhr

Benutzer-Avatar
Francisco Späth

Java <= 6.x erlaubt Ihnen nur, eine Ausnahme für jeden Catch-Block abzufangen:

try {

} catch (ExceptionType name) {

} catch (ExceptionType name) {

}

Dokumentation:

Jeder Catch-Block ist ein Ausnahmebehandler und verarbeitet den Ausnahmetyp, der durch sein Argument angegeben wird. Der Argumenttyp ExceptionType deklariert den Ausnahmetyp, den der Handler verarbeiten kann, und muss der Name einer Klasse sein, die von der Throwable-Klasse erbt.

Für Java 7 können Sie mehrere Ausnahmen in einem Catch-Block abfangen:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

Dokumentation:

In Java SE 7 und höher kann ein einzelner Catch-Block mehr als einen Ausnahmetyp behandeln. Diese Funktion kann die Codeduplizierung reduzieren und die Versuchung mindern, eine zu breite Ausnahme abzufangen.

Bezug:
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html

Wenn Sie nicht Java 7 verwenden, können Sie Ihre Ausnahmebehandlung in eine Methode extrahieren – auf diese Weise können Sie die Duplizierung zumindest minimieren

try {
   // try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }

  • Gute Antwort +1. Der Beispielcode ergibt keinen Sinn. Wenn Ihre Namenskonventionen dann gut sind ExtendsRuntimeException ist ein Exception. Der erste catch-Block ist also nicht erforderlich. Ein besseres Beispiel wäre catch(RuntimeExceptionA e ) { handleAB( e ) ; } catch ( RuntimeExceptionB e ) { handleAB ( e ) ; } catch ( RuntimeExceptionC e ) { handleC ( e ) ; }` Es ist nicht möglich, sie alle zu reduzieren catch ( RuntimeException e ).

    – Erinnerung

    26. Juni 2012 um 18:13 Uhr


  • Diese Vorgehensweise kann auch bei Java 7 erforderlich sein. Zum Beispiel, wenn Sie behandeln möchten IndexOutOfBoundException und (nicht RuntimeException) Throwable das gleiche, aber behandeln möchten (nicht IndexOutOfBoundsException) RuntimeException anders, dann ist die neue Java-7-Syntax nicht sinnvoll.

    – Erinnerung

    26. Juni 2012 um 18:56 Uhr

Benutzer-Avatar
Sarel Botha

Für Java < 7 können Sie if-else zusammen mit Exception verwenden:

try {
    // common logic to handle both exceptions
} catch (Exception ex) {
    if (ex instanceof Exception1 || ex instanceof Exception2) {

    }
    else {
        throw ex;
        // or if you don't want to have to declare Exception use
        // throw new RuntimeException(ex);
    }
}

Bearbeitet und ersetzt Throwable durch Exception.

Vor der Einführung von Java SE 7 waren wir es gewohnt, Code mit mehreren Catch-Anweisungen zu schreiben, die einem Try-Block zugeordnet waren. Ein ganz einfaches Beispiel:

 try {
  // some instructions
} catch(ATypeException e) {
} catch(BTypeException e) {
} catch(CTypeException e) {
}

Aber mit dem neuesten Update für Java können wir jetzt, anstatt mehrere Catch-Anweisungen zu schreiben, mehrere Ausnahmen in einer einzigen Catch-Klausel behandeln. Hier ist ein Beispiel, das zeigt, wie diese Funktion erreicht werden kann.

try {
// some instructions
} catch(ATypeException|BTypeException|CTypeException ex) {
   throw e;
}

Mehrere Ausnahmen in einer einzigen catch-Klausel vereinfachen also nicht nur den Code, sondern reduzieren auch die Redundanz des Codes. Ich habe diesen Artikel gefunden, der diese Funktion zusammen mit ihrer Implementierung sehr gut erklärt.
Verbesserte und bessere Ausnahmebehandlung von Java 7
Dies kann Ihnen auch helfen.

  • Ihre Antwort war 18 Monate zu spät und hat nichts Neues hinzugefügt. In solchen Fällen ist es besser, einfach die Antwort mit den für Sie nützlichen Informationen hochzustimmen.

    – Stefan C

    7. März 2018 um 3:07 Uhr

Benutzer-Avatar
Eli

http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html behandelt das Abfangen mehrerer Ausnahmen im selben Block.

 try {
     // your code
} catch (Exception1 | Exception2 ex) {
     // Handle 2 exceptions in Java 7
}

Ich mache Lernkarten, und dieser Thread war hilfreich, wollte nur meinen Senf dazu beitragen.

  • Ihre Antwort war 18 Monate zu spät und hat nichts Neues hinzugefügt. In solchen Fällen ist es besser, einfach die Antwort mit den für Sie nützlichen Informationen hochzustimmen.

    – Stefan C

    7. März 2018 um 3:07 Uhr

1319620cookie-checkIst es in Java möglich, zwei Ausnahmen im selben Catch-Block abzufangen? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy