Menu
Coddy logo textTech

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 geschlossen

Du 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 fr

Um 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.

challenge icon

Aufgabe

Einfach

Lass 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 Klasse Connection sollte AutoCloseable implementieren. Sie benötigt ein privates Feld für den Verbindungsnamen (String), einen Konstruktor, der den Namen entgegennimmt und [name] connection opened ausgibt, eine Methode query(String sql), die Executing on [name]: [sql] ausgibt, sowie die erforderliche Methode close(), die [name] connection closed ausgibt.
  • Session.java: Erstelle eine weitere automatisch schließbare Klasse, die eine Benutzersitzung simuliert. Deine Klasse Session sollte ebenfalls AutoCloseable implementieren. Füge ein privates Feld für den Benutzernamen (String), einen Konstruktor, der den Benutzernamen entgegennimmt und Session started for [username] ausgibt, eine Methode performAction(String action), die [username] performed: [action] ausgibt, sowie eine Methode close() hinzu, die Session 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 eine Connection mit dem angegebenen Namen zu erstellen. Rufe innerhalb des try-Blocks query("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 einer Connection (unter Verwendung desselben Namens) als auch mit einer Session (unter Verwendung des Benutzernamens), die in dieser Reihenfolge durch Semikolons getrennt deklariert werden. Rufe innerhalb des try-Blocks zuerst query("INSERT INTO logs") für die Verbindung und anschließend performAction mit 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
        
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Java-Compiler