1. Einführung
In der Programmierung gibt es oft Situationen, in denen eine Methode auf einen Fehler stößt, aber nicht weiß, wie sie ihn richtig behandeln soll. Zum Beispiel liest eine Methode eine Datei, weiß aber nicht, was zu tun ist, wenn die Datei fehlt: den Benutzer fragen? Das Programm beenden? Eine andere Datei versuchen? In solchen Fällen kann die Methode die Verantwortung „weiterreichen“ – das heißt, die Ausnahme in der Aufrufkette nach oben geben.
Das Durchreichen einer Ausnahme ist ein Mechanismus, der es einer Methode erlaubt, einen Fehler nicht selbst zu behandeln, sondern dem aufrufenden Code mitzuteilen: „Hier gibt es ein Problem – kümmere dich selbst darum!“
Analogie: Stellen Sie sich vor, Sie sind ein Mitarbeiter in einem Callcenter. Ein Kunde ruft mit einer Frage an, auf die Sie keine Antwort wissen. Anstatt zu raten, sagen Sie: „Einen Moment, ich verbinde Sie mit einem Spezialisten.“ Sie „reichen“ die Frage weiter.
Schlüsselwort throws: wie es funktioniert
In Java wird zum Durchreichen von Ausnahmen das Schlüsselwort throws in der Methodendeklaration verwendet.
Syntax:
returnType methodName(...) throws ExceptionType
{
// Code der Methode
}
Nach throws steht der Typ der Ausnahme, die in dieser Methode auftreten kann. Das ist wie eine Warnung für andere Entwickler: „Achtung! Diese Methode kann eine Ausnahme dieses Typs auslösen. Seien Sie darauf vorbereitet!“
Beispiel:
public void readFile(String filename) throws FileNotFoundException
{
FileReader reader = new FileReader(filename); // kann FileNotFoundException auslösen
// ...
}
Hier behandelt die Methode readFile den Fehler nicht selbst, sondern teilt mit: „Ich kann eine FileNotFoundException auslösen – der Aufrufer soll entscheiden, was zu tun ist.“
2. Wie sollte die aufrufende Methode reagieren?
Wenn Sie eine Methode aufrufen, die mit throws deklariert ist, haben Sie zwei Möglichkeiten:
- Die Ausnahme mit try-catch behandeln
- Die Ausnahme ebenfalls weiterreichen (in der eigenen Methode throws hinzufügen)
Variante 1: über try-catch behandeln
public static void main(String[] args)
{
try
{
readFile("data.txt");
}
catch (FileNotFoundException e)
{
System.out.println("Datei nicht gefunden: " + e.getMessage());
}
}
Hier fangen wir die Ausnahme und entscheiden selbst, was zu tun ist (zum Beispiel eine Meldung für den Benutzer ausgeben).
Variante 2: weiterreichen
public static void main(String[] args) throws FileNotFoundException
{
readFile("data.txt");
}
Nun liegt die Verantwortung für die Fehlerbehandlung bei dem, der main aufruft (in der Regel die JVM selbst – wenn der Fehler nicht behandelt wird, beendet sich das Programm mit einer Fehlermeldung).
3. Beispiel: Datei lesen mit durchgereichter Ausnahme
Vollständiges Beispiel mit IOException und Behandlung auf Ebene von main:
import java.io.*;
public class FileDemo
{
// Die Methode deklariert, dass sie eine IOException auslösen kann
public static void printFirstLine(String filename) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line = reader.readLine();
System.out.println("Erste Zeile: " + line);
reader.close();
}
public static void main(String[] args)
{
try
{
printFirstLine("nofile.txt");
}
catch (IOException e)
{
System.out.println("Fehler beim Lesen der Datei: " + e.getMessage());
}
}
}
Die Methode printFirstLine weiß nicht, was zu tun ist, wenn die Datei fehlt – sie reicht die Ausnahme einfach weiter. In main fangen wir den Fehler und geben eine Meldung aus.
4. Nützliche Feinheiten
Wann und warum Ausnahmen durchreichen?
- Wenn eine Methode nicht kann oder nicht sollte entscheiden, wie ein Fehler zu behandeln ist (z. B. Bibliothekscode).
- Wenn die Fehlerbehandlung vom Kontext abhängt (in einem Fall Programm beenden, im anderen – eine andere Datei versuchen).
- Um den Code nicht mit unnötigen try-catch zu überfrachten, wo es nicht nötig ist.
Best Practice: Reichen Sie Ausnahmen durch, wenn Sie sie nicht sinnvoll behandeln können. Fangen Sie Ausnahmen nicht nur pro forma!
Man kann mehrere Ausnahmen durchreichen
public void process() throws IOException, SQLException
{
// ...
}
Checked- und Unchecked-Ausnahmen: Erinnerung
Checked Exceptions (z. B. IOException, SQLException) – der Compiler verlangt, dass sie behandelt oder weitergereicht werden.
Unchecked Exceptions (z. B. NullPointerException, IllegalArgumentException) – der Compiler verlangt keine Behandlung; man muss sie in throws nicht angeben.
5. Typische Fehler beim Durchreichen von Ausnahmen
Fehler Nr. 1: throws für eine Checked-Ausnahme vergessen.
Wenn eine Methode eine Checked-Ausnahme auslösen kann, Sie diese aber nicht in throws deklarieren und auch nicht per try-catch behandeln – meldet der Compiler einen Fehler.
Fehler Nr. 2: Ausnahme fangen, aber nicht behandeln.
catch (Exception e) {} zu schreiben ist eine schlechte Praxis! Reichen Sie die Ausnahme lieber weiter, wenn Sie nicht wissen, was Sie damit tun sollen.
Fehler Nr. 3: Sie reichen einen zu allgemeinen Typ weiter.
Wenn eine Methode nur FileNotFoundException auslösen kann, schreiben Sie nicht throws Exception – das erschwert das Verständnis des Codes.
Fehler Nr. 4: Unchecked-Ausnahmen in throws weiterreichen.
Es hat keinen Sinn, throws NullPointerException zu schreiben – der Compiler verlangt das nicht, und das hilft der Fehlerbehandlung nicht.
GO TO FULL VERSION