Try-with-Resources-Muster
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 62 von 87.
Beim Arbeiten mit Ressourcen wie Dateistreams oder Datenbankverbindungen musst du sie nach der Verwendung immer schließen. Andernfalls riskierst du Speicherlecks. Der traditionelle Ansatz verwendet einen finally-Block, ist aber umständlich und fehleranfällig.
Die try-with-resources-Anweisung von Java schließt Ressourcen automatisch, wenn der Block abgeschlossen ist. Jede Klasse, die das AutoCloseable-Interface implementiert, kann mit dieser Syntax verwendet werden:
// Traditioneller Ansatz – ausführlich und riskant
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} finally {
if (reader != null) {
reader.close(); // Könnte auch eine Exception werfen!
}
}
// Try-with-resources – sauber und sicher
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Wird hier automatisch geschlossenDu kannst mehrere Ressourcen verwalten, indem du sie durch Semikolons trennst. Sie werden in umgekehrter Reihenfolge ihrer Deklaration geschlossen:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// Verwende beide Ressourcen
} // br wird zuerst geschlossen, dann frUm deine eigene automatisch schließbare Klasse zu erstellen, implementiere das AutoCloseable-Interface und seine einzige close()-Methode:
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}Dieses Muster stellt sicher, dass Ressourcen immer ordnungsgemäß freigegeben werden, selbst wenn während der Verarbeitung Ausnahmen auftreten.
Aufgabe
EinfachLass uns ein Ressourcenverwaltungssystem erstellen, das die Leistungsfähigkeit von try-with-resources demonstriert! Du wirst benutzerdefinierte automatisch schließbare Klassen erstellen, die das Verwalten von Verbindungen und Sitzungen simulieren und sicherstellen, dass sie immer ordnungsgemäß bereinigt werden.
Du wirst deinen Code auf drei Dateien verteilen:
Connection.java: Erstelle eine Klasse, die eine Datenbankverbindung simuliert. Deine KlasseConnectionsollteAutoCloseableimplementieren. Sie benötigt ein privates Feld für den Verbindungsnamen (String), einen Konstruktor, der den Namen entgegennimmt und[name] connection openedausgibt, eine Methodequery(String sql), dieExecuting on [name]: [sql]ausgibt, sowie die erforderliche Methodeclose(), die[name] connection closedausgibt.Session.java: Erstelle eine weitere automatisch schließbare Klasse, die eine Benutzersitzung simuliert. Deine KlasseSessionsollte ebenfallsAutoCloseableimplementieren. Füge ein privates Feld für den Benutzernamen (String), einen Konstruktor, der den Benutzernamen entgegennimmt undSession started for [username]ausgibt, eine MethodeperformAction(String action), die[username] performed: [action]ausgibt, sowie eine Methodeclose()hinzu, dieSession ended for [username]ausgibt.Main.java: Führe dein Ressourcenverwaltungssystem zusammen! Du erhältst drei Eingaben: einen Verbindungsnamen, einen Benutzernamen und eine auszuführende Aktion.Demonstriere zunächst die Verwaltung einer einzelnen Ressource. Gib
=== Single Resource ===aus und verwende dann try-with-resources, um eineConnectionmit dem angegebenen Namen zu erstellen. Rufe innerhalb des try-Blocksquery("SELECT * FROM users")auf. Die Verbindung sollte automatisch geschlossen werden, wenn der Block endet.Demonstriere als Nächstes mehrere Ressourcen. Gib eine Leerzeile und anschließend
=== Multiple Resources ===aus. Verwende try-with-resources sowohl mit einerConnection(unter Verwendung desselben Namens) als auch mit einerSession(unter Verwendung des Benutzernamens), die in dieser Reihenfolge durch Semikolons getrennt deklariert werden. Rufe innerhalb des try-Blocks zuerstquery("INSERT INTO logs")für die Verbindung und anschließendperformActionmit der Eingabeaktion für die Sitzung auf. Beobachte, wie Ressourcen in umgekehrter Reihenfolge geschlossen werden!
Du erhältst drei Eingaben in dieser Reihenfolge: Verbindungsname (String), Benutzername (String) und Aktion (String).
Beachte, wie try-with-resources die Notwendigkeit expliziter close-Aufrufe und finally-Blöcke beseitigt. Es ist garantiert, dass die Ressourcen auch dann geschlossen werden, wenn Ausnahmen auftreten, und mehrere Ressourcen werden in umgekehrter Reihenfolge ihrer Deklaration geschlossen!
Probier es selbst
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String connectionName = scanner.nextLine();
String username = scanner.nextLine();
String action = scanner.nextLine();
// === Single Resource ===
// TODO: Gib den Header aus
// TODO: Verwende try-with-resources, um eine Connection zu erstellen
// TODO: Inside the try block, call query("SELECT * FROM users")
// === Multiple Resources ===
// TODO: Gib eine leere Zeile und den Header aus
// TODO: Verwende try-with-resources mit sowohl Connection als auch Session
// TODO: Innerhalb des try-Blocks:
// - Call query("INSERT INTO logs") on the connection
// - Rufe performAction mit der Eingabe-action auf der session auf
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung10Exception Handling in OOP
Hierarchie der Exception-KlassenBenutzerdefinierte ExceptionsGeprüfte vs. ungeprüfte FehlerTry-with-Resources-MusterRückblick – Validierter Benutzer2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler