Comment utiliser Try With Resource en Java

Feb 21 2023
Comment gérer les exceptions à l'aide de l'instruction try-with-resource La construction Java try with resources, AKA Java try-with-resources, est un mécanisme de gestion des exceptions qui peut automatiquement fermer des ressources telles qu'un Java InputStream ou une connexion JDBC lorsque vous en avez terminé avec eux . Oracle a ajouté la construction try with resources au langage Java en 2011 pour aider à garantir que les objets tels que les sockets réseau, les connexions de base de données et les références aux fichiers et dossiers se terminent proprement après leur utilisation.

Comment gérer les exceptions à l'aide de l'instruction try-with-resource

La construction Java try with resources , AKA Java try-with-resources , est un mécanisme de gestion des exceptions qui peut automatiquement fermer des ressources telles qu'un Java InputStream ou une connexion JDBC lorsque vous en avez terminé.

Oracle a ajouté la construction try with resources au langage Java en 2011 pour aider à garantir que les objets tels que les sockets réseau, les connexions de base de données et les références aux fichiers et dossiers se terminent proprement après leur utilisation. Si vous ne fermez pas ces ressources après qu'un développeur leur a ouvert un descripteur, cela peut entraîner des fuites de mémoire , déclencher des routines de récupération de place évitables et solliciter le processeur d'un serveur .

· Avant Java 7
· Comment utiliser l'instruction try-with-resource ?
· Pourquoi dois-je utiliser l'instruction try-with-resource ?
· Exemple
· Exceptions supprimées
· Avantages de l'utilisation de try-with-resources
· Try-with-resources avec plusieurs ressources
· Java 9 — Variables effectivement finales

Avant Java 7

En Java, si vous utilisez une ressource comme des flux d'entrée ou de sortie, vous devez toujours la fermer après l'avoir utilisée. Il peut également lancer des exceptions, il doit donc être dans un bloc try-catch . La fermeture doit être dans le bloc finally . C'est du moins le cas jusqu'à Java 7. Cela présente plusieurs inconvénients :

  • Vous devriez vérifier si votre ressource est nulle avant de la fermer
  • La fermeture elle-même peut lever des exceptions, de sorte que vous avez finalement dû contenir un autre try-catch
  • Les programmeurs ont tendance à oublier de fermer leurs ressources

Comment utiliser l'instruction try-with-resource ?

Il a été initialement introduit dans Java 7 et l'idée sous-jacente était que le développeur n'a pas à se soucier de la gestion des ressources pour les ressources qu'il utilise uniquement dans un bloc try-catch-finally . Ceci est réalisé en supprimant le besoin de blocs finally , que les développeurs n'utilisaient que pour fermer les ressources dans la pratique.

En Java, l'instruction try-with-resources est une instruction try qui déclare une ou plusieurs ressources. La ressource est comme un objet qui doit être fermé après avoir terminé le programme. Lorsque l'exécution quitte le bloc try-with-resources , toute ressource ouverte dans le bloc try-with-resources est automatiquement fermée, que des exceptions soient levées soit depuis l'intérieur du bloc try-with-resources , soit lors de la tentative de fermeture les ressources.

Pour utiliser la fonctionnalité de langage try-with-resources de Java, les règles suivantes s'appliquent :

  • Tous les objets gérés par une instruction try with resources doivent implémenter l'interface AutoCloseable.
  • Plusieurs objets AutoCloseable peuvent être créés dans le bloc try with resources de Java.
  • Les objets déclarés dans une instruction try with resources ont une portée dans le bloc try, mais pas dans les blocs catch et finally.
  • La méthode close() des objets déclarés dans un bloc try with resources est invoquée, qu'une exception soit levée ou non lors de l'exécution.
  • Si une exception est levée dans la méthode close(), elle peut être classée comme une exception supprimée .

La ressource référencée par l'objet AutoCloseable sera toujours fermée si une instruction try with resources est utilisée, et les fuites de mémoire potentielles généralement causées par une mauvaise allocation des ressources sont éliminées.

Syntaxe

try(declare resources here) {
    // use resources
}
catch(FileNotFoundException e) {
    // exception handling
}

En termes simples, pour être fermée automatiquement, une ressource doit être à la fois déclarée et initialisée dans le try :

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Hello World");
}

La manière simple et évidente d'utiliser la nouvelle fonctionnalité try-with-resources consiste à remplacer le bloc try-catch-finally traditionnel et verbeux.

Comparons les exemples de code suivants.

Le premier est un bloc try-catch-finally typique :

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}"); background-repeat: no-repeat; background-position: center center; background-color: rgb(99, 177, 117);">Copy

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

En ce qui concerne les exceptions, il existe une différence entre le bloc try-catch-finally et le bloc try-with-resources. Si une exception est levée à la fois dans le bloc try et dans le bloc finally, la méthode renvoie l'exception levée dans le bloc finally.

Pour try-with-resources, si une exception est levée dans un bloc try et dans une instruction try-with-resources, la méthode renvoie l'exception levée dans le bloc try. Les exceptions levées par try-with-resources sont supprimées, c'est-à-dire que nous pouvons dire que le bloc try-with-resources lève des exceptions supprimées.

Pourquoi dois-je utiliser l'instruction try-with-resource ?

L'instruction try-with-resources garantit que chaque ressource est fermée à la fin de l'exécution de l'instruction . Si nous ne fermons pas les ressources, cela peut constituer une fuite de ressources et le programme pourrait également épuiser les ressources à sa disposition. c'est ce qui se passe principalement lorsque vous utilisez le bloc try-catch-finally

Avant Java SE 7, vous pouvez utiliser un bloc finally pour vous assurer qu'une ressource est fermée, que l' instruction try se termine normalement ou brusquement. L'exemple suivant utilise un bloc finally au lieu d'une instruction try -with-resources :

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
   
    FileReader fr = new FileReader(path);
    BufferedReader br = new BufferedReader(fr);
    try {
        return br.readLine();
    } finally {
        br.close();
        fr.close();
    }
}

Dans cet exemple, si la méthode readLine lève une exception et que l'instruction br.close() dans le bloc finally lève une exception, alors le FileReader a fui. Par conséquent, utilisez une instruction try -with-resources au lieu d'un bloc finally pour fermer les ressources de votre programme.

Exemple

L'exemple suivant lit la première ligne d'un fichier. Il utilise une instance de FileReader et BufferedReader pour lire les données du fichier. FileReader et BufferedReader sont des ressources qui doivent être fermées une fois que le programme en a terminé :

import java.io.*;
class Main {
  public static void main(String[] args) {
    String line;
    try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
      while ((line = br.readLine()) != null) {
        System.out.println("Line =>"+line);
      }
    } catch (IOException e) {
      System.out.println("IOException in try block =>" + e.getMessage());
    }
  }
}

Exceptions supprimées

Si un bloc try lève une exception et qu'une ou plusieurs exceptions sont levées par try-with-resources, les exceptions levées par try-with-resources sont supprimées. En d'autres termes, nous pouvons dire que les exceptions levées par try-with-resources sont des exceptions supprimées.

Vous pouvez obtenir ces exceptions en utilisant la méthode getSuppress() de la classe Throwable.

Exemple :

Dans l'exemple ci-dessus, des exceptions peuvent être levées à partir de l'instruction try-with-resources lorsque :

  • Le fichier test.txt est introuvable.
  • Fermeture de l' objet BufferedReader .

Si des exceptions sont levées à la fois du bloc try et de l'instruction try-with-resources , l'exception du bloc try est levée et l'exception de l' instruction try-with-resources est supprimée.

Récupération des exceptions supprimées

Dans Java 7 et versions ultérieures, les exceptions supprimées peuvent être récupérées en appelant la méthode Throwable.getSuppressed() à partir de l'exception levée par le bloc try .

getSuppress() Elle renvoie un tableau contenant toutes les exceptions qui ont été supprimées par l'instruction try-with-resources. Si aucune exception n'a été supprimée ou si la suppression est désactivée, un tableau vide est renvoyé.

Nous obtenons les exceptions supprimées dans le bloc catch .

catch(IOException e) {
  System.out.println("Thrown exception=>" + e.getMessage());
  Throwable[] suppressedExceptions = e.getSuppressed();
  for (int i=0; i<suppressedExceptions.length; i++) {
    System.out.println("Suppressed exception=>" + suppressedExceptions[i]);
  }
}

Voici les avantages de l'utilisation de try-with-resources :

  • Code plus lisible et facile à écrire.
  • Gestion automatique des ressources.
  • Le nombre de lignes de code est réduit.
  • Lorsque plusieurs ressources sont ouvertes dans try-with-resources, il les ferme dans l'ordre inverse pour éviter tout problème de dépendance.

Avant que Java 7 n'introduise cette fonctionnalité, nous devions utiliser le bloc finally pour nous assurer que la ressource est fermée afin d'éviter les fuites de ressources.

Voici un programme similaire à l'exemple 1 . Cependant, dans ce programme, nous avons utilisé le blocage final pour fermer les ressources.

Exemple : Fermer la ressource à l'aide du bloc finally

import java.io.*;
class Main {
  public static void main(String[] args) {
    BufferedReader br = null;
    String line;
    try {
      System.out.println("Entering try block");
      br = new BufferedReader(new FileReader("test.txt"));
      while ((line = br.readLine()) != null) {
        System.out.println("Line =>"+line);
      }
    } catch (IOException e) {
      System.out.println("IOException in try block =>" + e.getMessage());
    } finally {
      System.out.println("Entering finally block");
      try {
        if (br != null) {
          br.close();
        }
      } catch (IOException e) {
        System.out.println("IOException in finally block =>"+e.getMessage());
      }
    }
  }
}

Entering try block
Line =>line from test.txt file
Entering finally block

Remarquez également le bloc try…catch dans le bloc finally ? En effet, une IOException peut également se produire lors de la fermeture de l' instance BufferedReader à l'intérieur de ce bloc finally afin qu'elle soit également interceptée et gérée.

L' instruction try-with-resources effectue une gestion automatique des ressources . Nous n'avons pas besoin de fermer explicitement les ressources car JVM les ferme automatiquement. Cela rend le code plus lisible et plus facile à écrire.

try-with-resources Avec plusieurs ressources

Nous pouvons très bien déclarer plusieurs ressources dans un bloc try-with-resources en les séparant par un point-virgule :

try (Scanner scanner = new Scanner(new File("testRead.txt"));
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
    while (scanner.hasNext()) {
	writer.print(scanner.nextLine());
    }
}

Avant Java 9, nous ne pouvions utiliser de nouvelles variables qu'à l'intérieur d'un bloc try-with-resources :

try (Scanner scanner = new Scanner(new File("testRead.txt")); 
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { 
    // omitted
}"); background-repeat: no-repeat; background-position: center center; background-color: rgb(99, 177, 117);">Copy

final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) { 
    // omitted
}"); background-repeat: no-repeat; background-position: center center; background-color: rgb(99, 177, 117);">Copy

Comme indiqué ci-dessus, la variable scanner est déclarée explicitement finale , nous pouvons donc l'utiliser avec le bloc try-with-resources . Bien que la variable writer ne soit pas explicitement finale, elle ne change pas après la première affectation. Ainsi, nous pouvons également utiliser la variable writer .

Bon apprentissage

Rejoindre Mouad Oumous Java WhatsApp Group REJOINDRE

Rejoindre Mouad Oumous Telegram Channel REJOINDRE

Soutenez notre publication en la suivant

Guide du mappage d'objets avec ModelMapper en Java Premiers pas avec Spring Boot : un didacticiel complet pour les débutants Spring Boot Security | authentification unique | OAuth2 avec Okta Question d'entretien basée sur le flux Java8 la plus fréquemment posée - Partie 2 Codage : Aplatir un tableau en Javascript Question d'entretien basée sur le flux Java8 la plus fréquemment posée - Partie 1