Verkettete Ausnahmen in Java

1. Übersicht

In diesem Artikel werden wir uns kurz mit Exception befassen und die verketteten Ausnahmen in Java ausführlich erläutern.

Einfach ausgedrückt ist eine Ausnahme ein Ereignis, das den normalen Ablauf der Programmausführung stört. Lassen Sie uns nun genau sehen, wie wir Ausnahmen verketten können, um eine bessere Semantik daraus zu ziehen.

2. Verkettete Ausnahmen

Mit der verketteten Ausnahme können Sie eine Situation identifizieren, in der eine Ausnahme eine andere Ausnahme in einer Anwendung verursacht.

Stellen Sie sich beispielsweise eine Methode vor, die eine ArithmeticException auslöst, weil versucht wird, durch Null zu teilen. Die eigentliche Ausnahmeursache war jedoch ein E / A-Fehler, der dazu führte, dass der Divisor Null war. Die Methode löst die ArithmeticException für den Aufrufer aus. Der Anrufer würde die tatsächliche Ursache einer Ausnahme nicht kennen . In solchen Situationen wird eine verkettete Ausnahme verwendet.

Dieses Konzept wurde in JDK 1.4 eingeführt.

Mal sehen, wie verkettete Ausnahmen in Java unterstützt werden.

3. Throwable Klasse

Die Throwable- Klasse verfügt über einige Konstruktoren und Methoden zur Unterstützung verketteter Ausnahmen. Schauen wir uns zunächst die Konstruktoren an.

  • Throwable (Throwable-Ursache) - Throwable verfügt über einen einzelnen Parameter, der die tatsächliche Ursache einer Ausnahme angibt.
  • Auslösbar (String desc, Auslösbare Ursache) - Dieser Konstruktor akzeptiert eine Ausnahmebeschreibung mit der tatsächlichen Ursache einer Ausnahme .

Schauen wir uns als nächstes die Methoden an, die diese Klasse bietet:

  • getCause () -Methode - Diese Methode gibt die tatsächliche Ursache zurück, die der aktuellen Ausnahme zugeordnet ist .
  • initCause () -Methode - Legt eine zugrunde liegende Ursache beim Aufrufen von Exception fest .

4. Beispiel

Schauen wir uns nun das Beispiel an, in dem wir unsere eigene Ausnahmebeschreibung festlegen und eine verkettete Ausnahme auslösen :

public class MyChainedException { public void main(String[] args) { try { throw new ArithmeticException("Top Level Exception.") .initCause(new IOException("IO cause.")); } catch(ArithmeticException ae) { System.out.println("Caught : " + ae); System.out.println("Actual cause: "+ ae.getCause()); } } }

Wie vermutet, führt dies zu:

Caught: java.lang.ArithmeticException: Top Level Exception. Actual cause: java.io.IOException: IO cause.

5. Warum verkettete Ausnahmen?

Wir müssen die Ausnahmen verketten, um Protokolle lesbar zu machen. Schreiben wir zwei Beispiele. Erstens ohne Verkettung der Ausnahmen und zweitens mit verketteten Ausnahmen. Später werden wir vergleichen, wie sich Protokolle in beiden Fällen verhalten.

Zu Beginn erstellen wir eine Reihe von Ausnahmen:

class NoLeaveGrantedException extends Exception { public NoLeaveGrantedException(String message, Throwable cause) { super(message, cause); } public NoLeaveGrantedException(String message) { super(message); } } class TeamLeadUpsetException extends Exception { // Both Constructors }

Beginnen wir nun damit, die obigen Ausnahmen in Codebeispielen zu verwenden.

5.1. Ohne Verkettung

Schreiben wir ein Beispielprogramm, ohne unsere benutzerdefinierten Ausnahmen zu verketten.

public class MainClass { public void main(String[] args) throws Exception { getLeave(); } void getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { e.printStackTrace(); throw new NoLeaveGrantedException("Leave not sanctioned."); } } void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team Lead Upset"); } }

Im obigen Beispiel sehen Protokolle folgendermaßen aus:

com.baeldung.chainedexception.exceptions.TeamLeadUpsetException: Team lead Upset at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:46) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Exception in thread "main" com.baeldung.chainedexception.exceptions. NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:37) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29)

5.2. Mit Verkettung

Als nächstes schreiben wir ein Beispiel mit der Verkettung unserer benutzerdefinierten Ausnahmen:

public class MainClass { public void main(String[] args) throws Exception { getLeave(); } public getLeave() throws NoLeaveGrantedException { try { howIsTeamLead(); } catch (TeamLeadUpsetException e) { throw new NoLeaveGrantedException("Leave not sanctioned.", e); } } public void howIsTeamLead() throws TeamLeadUpsetException { throw new TeamLeadUpsetException("Team lead Upset."); } }

Schauen wir uns zum Schluss die Protokolle an, die mit verketteten Ausnahmen erhalten wurden:

Exception in thread "main" com.baeldung.chainedexception.exceptions .NoLeaveGrantedException: Leave not sanctioned. at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:36) at com.baeldung.chainedexception.exceptions.MainClass .main(MainClass.java:29) Caused by: com.baeldung.chainedexception.exceptions .TeamLeadUpsetException: Team lead Upset. at com.baeldung.chainedexception.exceptions.MainClass .howIsTeamLead(MainClass.java:44) at com.baeldung.chainedexception.exceptions.MainClass .getLeave(MainClass.java:34) ... 1 more

Wir können die angezeigten Protokolle leicht vergleichen und daraus schließen, dass die verketteten Ausnahmen zu saubereren Protokollen führen.

In diesem Artikel haben wir uns das Konzept der verketteten Ausnahmen angesehen.

Die Implementierung aller Beispiele finden Sie im Github-Projekt - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.