Menu

Java try-catch: Ausnahmen behandeln, ohne abzustürzen

Wie man try-catch in Java zur Ausnahmebehandlung nutzt: bestimmte Typen abfangen, der finally-Block, try-with-resources und die Fehler, die Bugs verstecken.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Eine Ausnahme abfangen, statt abzustürzen

Du weißt bereits, dass Java eine Ausnahme wirft, wenn etwas schiefgeht, und dass eine unbehandelte Ausnahme dein Programm mit einem Stacktrace anhält. Ein try-catch-Block ist dein Weg, die Kontrolle zu übernehmen: Du umschließt den riskanten Code mit try, und wenn er eine Ausnahme wirft, springt Java in den passenden catch-Block, statt abzustürzen.

In dem Moment, in dem 10 / 0 die Ausnahme wirft, wird der Rest des try-Blocks übersprungen und die Kontrolle geht an das catch über. Nachdem das catch durchgelaufen ist, läuft die Ausführung normal weiter - das Programm stirbt nicht.

Die catch-Variable enthält die Ausnahme

Das e in catch (ArithmeticException e) ist ein echtes Objekt. Es trägt Informationen darüber, was schiefgelaufen ist - am nützlichsten ist eine Nachricht:

e.getMessage() liefert eine kurze Beschreibung. Beim Debuggen gibt e.printStackTrace() den vollständigen Trace aus, der genau zeigt, woher die Ausnahme kam - greif darauf zurück, wenn eine Nachricht allein nicht ausreicht, um die Ursache zu finden.

Den spezifischen Typ abfangen, nicht alles

Ein catch-Block fängt nur Ausnahmen ab, die zu seinem deklarierten Typ (oder einer Unterklasse) passen. Der größte Anfängerfehler ist, Exception abzufangen, um ein Problem "verschwinden" zu lassen:

// Mach das nicht - es versteckt echte Bugs
try {
    doWork();
} catch (Exception e) {
    // verschluckt NullPointerException, Tippfehler, Logikfehler... alles
}

Fange den engsten Typ ab, den du wirklich behandeln kannst. Wenn du fehlerhafte Zahleneingaben erwartest, fange NumberFormatException ab. Alles, was du nicht vorhergesehen hast, sollte weiterpropagieren dürfen, damit du tatsächlich davon erfährst, statt stillschweigend in einem kaputten Zustand weiterzulaufen.

Mehrere Ausnahmetypen behandeln

Du kannst mehrere catch-Blöcke stapeln. Java prüft sie von oben nach unten und führt den ersten passenden aus, also ordne sie vom spezifischsten zum allgemeinsten:

Wenn sich zwei Typen dieselbe Behandlung teilen, verwende ein einzelnes Multi-catch mit |, statt den Block zu duplizieren:

Ein Fallstrick: Ein allgemeinerer Typ muss nach den spezifischen kommen. catch (Exception e) an den Anfang zu stellen, macht die späteren, spezifischeren Blöcke unerreichbar, und der Compiler lehnt das ab.

finally läuft immer

Ein finally-Block läuft nach dem try und jedem catch, unabhängig davon, was passiert ist - Erfolg, eine abgefangene Ausnahme oder sogar ein vorzeitiges return. Hier gehören Aufräumarbeiten hin, die immer passieren müssen.

"Closing resource" wird ausgegeben, egal ob die Ausnahme ausgelöst wird oder nicht. Vermeide es allerdings, aus dem Inneren eines finally ein return auszuführen - das kann eine Ausnahme stillschweigend verwerfen oder einen aus dem try-Block zurückgegebenen Wert überschreiben.

try-with-resources schließt Dinge für dich

Wenn du mit etwas arbeitest, das geschlossen werden muss - einer Datei, einer Netzwerkverbindung, einem Datenbank-Statement - schließt es das deklarieren innerhalb von try (...) automatisch, wenn der Block endet, selbst wenn eine Ausnahme geworfen wird. Jeder Typ, der AutoCloseable implementiert, funktioniert.

Das ersetzt das alte Muster, im try zu öffnen und im finally zu schließen, und ist weniger fehleranfällig, weil du das Schließen nicht vergessen kannst. Bevorzuge es immer dann, wenn du es mit einer schließbaren Ressource zu tun hast.

Nutze Ausnahmen nicht für die normale Ablaufsteuerung

try-catch ist für außergewöhnliche Situationen gedacht, nicht für gewöhnliche Bedingungen. Eine Ausnahme abzufangen ist teurer als eine einfache Prüfung und macht den Code schwerer lesbar. Wenn du die Bedingung vorab testen kannst, tu das stattdessen:

// Vermeiden: einen catch nutzen, um auf einen fehlenden Schlüssel zu testen
try {
    process(map.get(key).trim());
} catch (NullPointerException e) {
    // fehlenden Schlüssel behandeln
}

// Bevorzugen: explizit prüfen
String value = map.get(key);
if (value != null) {
    process(value.trim());
}

Reserviere catch für Dinge, die wirklich außerhalb deiner Kontrolle liegen - fehlerhafte Benutzereingaben, fehlende Dateien, Netzwerkausfälle.

Als Nächstes: NullPointerException

Die mit Abstand häufigste Ausnahme, die du in Java abfangen (und verursachen) wirst, ist die NullPointerException - sie taucht in dem Moment auf, in dem du eine Methode auf etwas aufrufst, das sich als null herausstellt. Als Nächstes schauen wir uns genau an, was sie auslöst, wie man ihren Stacktrace liest und welche Gewohnheiten sie von vornherein verhindern.

Häufig gestellte Fragen

Wie verwendet man try-catch in Java?

Schreibe den Code, der eine Ausnahme werfen könnte, in einen try-Block und füge dann einen catch-Block hinzu, der den Ausnahmetyp benennt, den du behandeln möchtest: try { risky(); } catch (IOException e) { ... }. Wenn der Code im try eine passende Ausnahme wirft, springt Java direkt in den catch-Block, statt abzustürzen. Die Variable (e) enthält das Ausnahmeobjekt, sodass du ihre Nachricht mit e.getMessage() auslesen kannst.

Wofür ist der finally-Block in Java da?

Ein finally-Block läuft nach try/catch in jedem Fall - egal ob der Code erfolgreich war, eine Ausnahme geworfen hat oder sogar vorzeitig ein return ausgeführt wurde. Er ist der Ort für Aufräumarbeiten, die immer passieren müssen, etwa das Schließen einer Datei oder das Freigeben eines Locks. Zum Schließen von Ressourcen ist try-with-resources meist sauberer, weil es sie automatisch schließt.

Sollte man Exception oder einen bestimmten Ausnahmetyp abfangen?

Fange den spezifischsten Typ ab, den du tatsächlich behandeln kannst. Exception (oder schlimmer noch Throwable) abzufangen, verschluckt jedes Problem - einschließlich Bugs wie NullPointerException - und verbirgt die eigentliche Ursache. Fange NumberFormatException ab, wenn du genau das erwartest, und lass unerwartete Ausnahmen weiterpropagieren, damit du von ihnen erfährst.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S