Menu
Coddy logo textTech

Pattern Try-with-resources

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 62 sur 87.

Lorsque tu travailles avec des ressources comme des flux file ou des connection à une base de données, tu dois toujours les close lorsque tu as terminé. Sinon, tu risques des fuites mémoire. L’approach traditionnelle utilise un finally block, mais elle est verbeuse et sujette aux erreurs.

L’instruction try-with-resources de Java ferme automatiquement les ressources lorsque le bloc s’achève. Toute classe qui implémente l’interface AutoCloseable peut être utilisée avec cette syntaxe :

// Approche traditionnelle - verbeuse et risquée
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
} finally {
    if (reader != null) {
        reader.close();  // Pourrait également lever une exception !
    }
}

// Try-with-resources - propre et sûr
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
}  // Fermé automatiquement ici

Vous pouvez gérer plusieurs ressources en les séparant par des points-virgules. Elles sont fermées dans l’ordre inverse de leur déclaration :

try (FileReader fr = new FileReader("input.txt");
     BufferedReader br = new BufferedReader(fr)) {
    // Utiliser les deux ressources
}  // br fermé en premier, puis fr

Pour créer votre propre classe à fermeture automatique, implémentez l’interface AutoCloseable et son unique méthode close() :

public class DatabaseConnection implements AutoCloseable {
    public DatabaseConnection() {
        System.out.println("Connection opened");
    }
    
    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

Ce modèle garantit que les ressources sont toujours correctement libérées, même si des exceptions surviennent pendant le traitement.

challenge icon

Défi

Facile

Construisons un système de gestion des ressources qui démontre la puissance de try-with-resources ! Vous allez créer des classes personnalisées auto-fermables qui simulent la gestion de connexions et de sessions, en garantissant qu'elles sont toujours correctement libérées.

Vous organiserez votre code sur trois fichiers :

  • Connection.java : créez une classe qui simule une connexion à une base de données. Votre classe Connection doit implémenter AutoCloseable. Elle doit contenir un champ privé pour le nom de la connexion (String), un constructeur qui prend le nom et affiche [name] connection opened, une méthode query(String sql) qui affiche Executing on [name]: [sql], ainsi que la méthode close() requise, qui affiche [name] connection closed.
  • Session.java : créez une autre classe auto-fermable qui simule une session utilisateur. Votre classe Session doit également implémenter AutoCloseable. Ajoutez un champ privé pour le nom d'utilisateur (String), un constructeur qui prend le nom d'utilisateur et affiche Session started for [username], une méthode performAction(String action) qui affiche [username] performed: [action], ainsi qu'une méthode close() qui affiche Session ended for [username].
  • Main.java : assemblez votre système de gestion des ressources ! Vous recevrez trois entrées : un nom de connexion, un nom d'utilisateur et une action à effectuer.

    Commencez par démontrer la gestion d'une seule ressource. Affichez === Single Resource ===, puis utilisez try-with-resources pour créer une Connection avec le nom fourni. À l'intérieur du bloc try, appelez query("SELECT * FROM users"). La connexion doit se fermer automatiquement lorsque le bloc se termine.

    Ensuite, démontrez la gestion de plusieurs ressources. Affichez une ligne vide, puis === Multiple Resources ===. Utilisez try-with-resources avec à la fois une Connection (en utilisant le même nom) et une Session (en utilisant le nom d'utilisateur), déclarées dans cet ordre et séparées par des points-virgules. À l'intérieur du bloc try, appelez d'abord query("INSERT INTO logs") sur la connexion, puis appelez performAction avec l'action fournie en entrée sur la session. Observez comment les ressources se ferment dans l'ordre inverse !

Vous recevrez trois entrées dans l'ordre suivant : nom de connexion (String), nom d'utilisateur (String) et action (String).

Remarquez comment try-with-resources élimine le besoin d'appels explicites à close et de blocs finally. Les ressources sont assurées de se fermer même si des exceptions surviennent, et les ressources multiples se ferment dans l'ordre inverse de leur déclaration !

Essayez vous-même

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: Affiche l'en-tête
        // TODO: Utilise try-with-resources pour créer une Connection
        // TODO: Inside the try block, call query("SELECT * FROM users")
        
        // === Multiple Resources ===
        // TODO: Affiche une ligne vide et l'en-tête
        // TODO: Utilise try-with-resources avec Connection et Session
        // TODO: À l'intérieur du bloc try :
        //       - Call query("INSERT INTO logs") on the connection
        //       - Appelle performAction avec l'action en entrée sur la session
        
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Java en ligne