try-with-resources / context managers
Klausur-Klassiker. Bei Ressourcen (Datei, DB-Verbindung, Stream) MUSS man hinterher schließen, auch im Fehlerfall.
Alte Methode (Java vor 7):
FileReader fr = null;
try {
fr = new FileReader("data.txt");
// arbeit damit...
} finally {
if (fr != null) fr.close(); // muss in finally!
}
Neu (try-with-resources):
try (FileReader fr = new FileReader("data.txt")) {
// arbeit damit...
}
// fr.close() wird AUTOMATISCH aufgerufen, auch bei Exception
// Falls beim close() selbst eine Exception fliegt, wird sie als
// suppressed Exception angehängt (e.getSuppressed()), die primäre
// Exception aus dem try-Block bleibt die Haupt-Exception.
Voraussetzung: die Ressource muss AutoCloseable implementieren. Viele Standard-Klassen tun das (Reader, Writer, Stream, Connection).
In Python macht das with:
with open("data.txt") as f:
# arbeit damit...
# f.close() wird AUTOMATISCH aufgerufen
Best Practices
❌ Nicht alles fangen
try {
// 200 Zeilen Code
} catch (Exception e) {
// alles still abfangen
}
So versteckst du Bugs. Du weißt nie was schief lief.
❌ Exception schlucken
try {
// ...
} catch (IOException e) {
// do nothing ← BAD
}
Mindestens loggen. Sonst verschwindet der Fehler spurlos.
✅ Spezifisch fangen
try {
Files.write(path, data);
} catch (FileNotFoundException e) {
// Datei nicht da → Default benutzen
} catch (IOException e) {
// anderes I/O-Problem → höher melden
throw new RuntimeException("I/O-Fehler", e);
}
✅ try-Blöcke klein und logisch zusammenhängend halten
Nicht unnötig 100 Zeilen einpacken. Aber: oft gehören mehrere zusammenhängende Operationen in denselben try, z. B. Ressource öffnen, lesen, parsen, schließen.
✅ Exceptions nicht für normalen Kontrollfluss missbrauchen
Exceptions sollten nicht als if-Ersatz oder Schleifensteuerung verwendet werden. Aber: bei Parsing von Nutzereingaben ist try { Integer.parseInt(s); } catch (NumberFormatException e) { ... } oft die idiomatische Lösung, vorab-Regex kann doppelte Logik erzeugen.
// Pragmatisch: Parsing mit catch ist okay
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return 0; // Default bei ungültiger Eingabe
}
// Anti-Pattern: Exception als Schleifensteuerung
try {
while (true) list.get(i++); // ← so NICHT
} catch (IndexOutOfBoundsException e) { /* Schleifenende */ }
Exceptions sind teurer (Stack-Trace-Aufbau kostet Zeit) als normale if-Verzweigungen, für normale Schleifen- oder Programmsteuerung also ungeeignet.