So funktioniert Multi-Catch - 1

„Noch ein paar interessante Lektionen. Oh, wie sehr ich es liebe zu unterrichten!“

„Ich will dir zeigen, wie mehrere catch-Blöcke funktionieren. Es ist ganz einfach: Wenn Ausnahmen in einem try-Block auftreten, springt die Ausführung zum ersten catch-Block.

„Wenn ein Typ, der in den Klammern des catch-Blocks angegeben ist, mit dem Typ der ausgelösten Ausnahme übereinstimmt, beginnt die Ausführung innerhalb dieses Blocks. Andernfalls springen wir zum nächsten catch-Block, wo die gleiche Prüfung durchgeführt wird.“

„Wenn uns die catch-Blöcke ausgehen und die Ausnahme nicht abgefangen wurde, wird sie erneut ausgelöst, und die aktuelle Methode wird vorzeitig beendet.“

„Verstehe. Es wird schließlich der catch-Block ausgeführt, der mit der Ausnahmeart übereinstimmt.“

„Ja, richtig. In Wirklichkeit ist das allerdings etwas komplizierter.“ Klassen können von anderen Klassen erben. Wenn eine Kuh-Klasse von einer Tier-Klasse erbt, kann das Kuh-Objekt nicht nur von einer Kuh-Variable, sondern auch von einer Tier-Variable referenziert werden.“

„Und?“

„Da alle Ausnahmen von Exception oder RuntimeException erben (die wiederum ebenfalls von Exception erbt), können sie weiterhin mit ‚catch (Exception e)‘ oder ‚catch (RuntimeException e)‘ abgefangen werden.“

„Und?“

„Wir können daher zwei Schlussfolgerungen ziehen. Erstens kannst du mit ‚catch (Exception e)‘ jede Ausnahme abfangen. Zweitens ist die Reihenfolge der catch-Blöcke entscheidend.

„Hier ein paar Beispiele:“

„Die ArithmeticException, die auftritt, nachdem wir durch 0 geteilt haben, wird im zweiten catch-Block abgefangen.“

Code
try
{
    System.out.println("Vor dem Aufruf von methode1.");
    int a = 1 / 0;
    System.out.println("Nach dem Aufruf von methode1. Das wird nie angezeigt.");
}
catch (NullPointerException e)
{
    System.out.println("Nullreferenz. Die Ausnahme wurde abgefangen.");
}
catch (ArithmeticException e)
{
    System.out.println("Division durch Null. Die Ausnahme wurde abgefangen.");
}
catch (Exception e)
{
    System.out.println("Alle anderen Fehler. Die Ausnahme wurde abgefangen.");
}

„Im folgenden Beispiel wird die ArithmeticException im ersten catch-Block abgefangen, da alle Ausnahmen von Exception erben, d.h. Exception deckt alle Ausnahmen ab.

Code
try
{
    System.out.println("Vor dem Aufruf von methode1.");
    int a = 1/0;
    System.out.println("Nach dem Aufruf von methode1. Das wird nie angezeigt.");
}
catch (Exception e)
{
    System.out.println("Alle anderen Fehler. Die Ausnahme wurde abgefangen.");
}
catch (NullPointerException e)
{
    System.out.println("Nullreferenz. Die Ausnahme wurde abgefangen.");
}
catch (ArithmeticException e)
{
    System.out.println("Geteilt durch Null. Die Ausnahme wurde abgefangen.");
}

„Im folgenden Beispiel wird ArithmeticException nicht abgefangen. Sie wird an die aufrufende Methode zurückgeworfen.“

Code
try
{
    System.out.println("Vor dem Aufruf von methode1.");
    int a = 1/0;
    System.out.println("Nach dem Aufruf von methode1. Das wird nie angezeigt.");
}
catch (NullPointerException e)
{
    System.out.println("Nullreferenz. Die Ausnahme wurde abgefangen.");
}

„Das macht die Sache etwas verständlicher. Diese Ausnahmen sind nicht gerade das einfachste Thema.“

„Das scheint nur so. Sie sind eigentlich eines der einfachsten Dinge in Java.“

„Ich weiß nicht, ob ich glücklich oder traurig darüber sein soll…“