Pattern Try-with-resources
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 62 sur 87.
Lorsque vous travaillez avec des ressources telles que des flux de fichiers ou des connexions à des bases de données, vous devez toujours les fermer une fois terminé — sinon vous risquez des fuites de mémoire. L'approche traditionnelle utilise un bloc finally, mais elle est verbeuse et sujette aux erreurs.
L'instruction try-with-resources de Java ferme automatiquement les ressources lorsque le bloc se termine. 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 iciVous 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 est fermé en premier, puis frPour créer votre propre classe auto-closeable, implémentez l'interface AutoCloseable et sa seule 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 pattern garantit que les ressources sont toujours correctement libérées, même si des exceptions surviennent pendant le traitement.
Défi
FacileConstruisons un système de gestion de ressources qui démontre la puissance du try-with-resources ! Vous allez créer des classes auto-closeable personnalisées qui simulent la gestion de connexions et de sessions, en garantissant qu'elles soient toujours correctement nettoyées.
Vous organiserez votre code sur trois fichiers :
Connection.java: Créez une classe qui simule une connexion à une base de données. Votre classeConnectiondoit implémenterAutoCloseable. Elle a besoin d'un champ privé pour le nom de la connexion (String), d'un constructeur qui prend le nom et affiche[name] connection opened, d'une méthodequery(String sql)qui afficheExecuting on [name]: [sql], et de la méthodeclose()requise qui affiche[name] connection closed.Session.java: Créez une autre classe auto-closeable qui simule une session utilisateur. Votre classeSessiondoit également implémenterAutoCloseable. Incluez un champ privé pour le nom d'utilisateur (String), un constructeur qui prend le nom d'utilisateur et afficheSession started for [username], une méthodeperformAction(String action)qui affiche[username] performed: [action], et une méthodeclose()qui afficheSession ended for [username].Main.java: Rassemblez votre système de gestion de ressources ! Vous recevrez trois entrées : un nom de connexion, un nom d'utilisateur et une action à effectuer.Tout d'abord, démontrez la gestion d'une ressource unique. Affichez
=== Single Resource ===, puis utilisez try-with-resources pour créer uneConnectionavec le nom donné. À l'intérieur du bloc try, appelezquery("SELECT * FROM users"). La connexion doit se fermer automatiquement à la fin du bloc.Ensuite, démontrez la gestion de ressources multiples. Affichez une ligne vide, puis
=== Multiple Resources ===. Utilisez try-with-resources avec à la fois uneConnection(en utilisant le même nom) et uneSession(en utilisant le nom d'utilisateur), déclarées dans cet ordre avec des points-virgules. À l'intérieur du bloc try, appelez d'abordquery("INSERT INTO logs")sur la connexion, puis appelezperformActionavec l'action d'entrée sur la session. Observez comment les ressources se ferment dans l'ordre inverse !
Vous recevrez trois entrées dans l'ordre : le nom de la connexion (String), le nom d'utilisateur (String) et l'action (String).
Remarquez comment try-with-resources élimine le besoin d'appels de fermeture explicites et de blocs finally. Les ressources sont garanties d'être fermées même si des exceptions surviennent, et les ressources multiples se ferment dans l'ordre inverse de leur déclaration !
Aide-mémoire
L'instruction try-with-resources ferme automatiquement les ressources lorsque le bloc se termine. Toute classe implémentant AutoCloseable peut être utilisée :
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
} // Fermé automatiquement iciPlusieurs ressources peuvent être gérées en les séparant par des points-virgules. Elles se ferment 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 frPour créer une classe auto-closeable personnalisée, implémentez l'interface AutoCloseable et sa méthode close() :
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}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();
// === Ressource unique ===
// TODO: Afficher l'en-tête
// TODO: Utiliser try-with-resources pour créer une Connection
// TODO: À l'intérieur du bloc try, appeler query("SELECT * FROM users")
// === Ressources multiples ===
// TODO: Afficher une ligne vide et l'en-tête
// TODO: Utiliser try-with-resources avec Connection et Session
// TODO: À l'intérieur du bloc try :
// - Appeler query("INSERT INTO logs") sur la connexion
// - Appeler performAction avec l'action d'entrée sur la session
}
}
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
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé10Gestion des exceptions en POO
Hiérarchie des classes d'exceptionExceptions personnaliséesErreurs Checked vs UncheckedPattern Try-with-resourcesRécapitulatif - Utilisateur validé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur