In diesem Tutorial lernen wir die Anweisung try-with-resources kennen, um Ressourcen automatisch zu schließen.
Die try-with-resources
Anweisung schließt automatisch alle Ressourcen am Ende der Anweisung. Eine Ressource ist ein Objekt, das am Ende des Programms geschlossen werden soll.
Die Syntax lautet:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Wie aus der obigen Syntax hervorgeht, deklarieren wir die try-with-resources
Anweisung mit:
- Deklarieren und Instanziieren der Ressource innerhalb der
try
Klausel. - Angeben und Behandeln aller Ausnahmen, die beim Schließen der Ressource ausgelöst werden können.
Hinweis: Mit der Anweisung try-with-resources werden alle Ressourcen geschlossen, die die AutoCloseable-Schnittstelle implementieren.
Nehmen wir ein Beispiel, das die try-with-resources
Aussage implementiert .
Beispiel 1: Versuchen mit Ressourcen
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()); ) ) )
Ausgabe, wenn die Datei test.txt nicht gefunden wird.
IOException im Try-with-Resources-Block => test.txt (Keine solche Datei oder kein solches Verzeichnis)
Ausgabe, wenn die Datei test.txt gefunden wird.
Eingabe des Try-with-Resources-Blocks Line => Test Line
In diesem Beispiel verwenden wir eine Instanz von BufferedReader, um Daten aus der test.txt
Datei zu lesen .
Durch das Deklarieren und Instanziieren des BufferedReader in der try-with-resources
Anweisung wird sichergestellt, dass seine Instanz geschlossen wird, unabhängig davon, ob die try
Anweisung normal ausgeführt wird oder eine Ausnahme auslöst.
Wenn eine Ausnahme auftritt, kann sie mit den Ausnahmebehandlungsblöcken oder dem Schlüsselwort throw behandelt werden.
Unterdrückte Ausnahmen
Im obigen Beispiel können Ausnahmen von der try-with-resources
Anweisung ausgelöst werden, wenn:
- Die Datei wurde
test.txt
nicht gefunden. - Schließen des
BufferedReader
Objekts.
Eine Ausnahme kann auch aus dem try
Block ausgelöst werden , da das Lesen einer Datei jederzeit aus vielen Gründen fehlschlagen kann.
Wenn Ausnahmen sowohl vom try
Block als auch von der try-with-resources
Anweisung try
ausgelöst werden , wird die Ausnahme vom Block ausgelöst und die Ausnahme von der try-with-resources
Anweisung unterdrückt.
Unterdrückte Ausnahmen abrufen
In Java 7 und höher können die unterdrückten Ausnahmen durch Aufrufen der Throwable.getSuppressed()
Methode aus der vom try
Block ausgelösten Ausnahme abgerufen werden .
Diese Methode gibt ein Array aller unterdrückten Ausnahmen zurück. Wir bekommen die unterdrückten Ausnahmen im catch
Block.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Vorteile der Verwendung von Try-with-Resources
Hier sind die Vorteile der Verwendung von Try-with-Resources:
1. Schließlich Block nicht erforderlich, um die Ressource zu schließen
Bevor Java 7 diese Funktion einführte, mussten wir den finally
Block verwenden, um sicherzustellen, dass die Ressource geschlossen ist, um Ressourcenlecks zu vermeiden.
Hier ist ein Programm, das Beispiel 1 ähnelt . In diesem Programm haben wir jedoch finally block verwendet, um Ressourcen zu schließen.
Beispiel 2: Schließen Sie die Ressource mit dem finally-Block
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()); ) ) ) )
Ausgabe
Try-Block eingeben Zeile => Zeile aus der Datei test.txt Endlich Block eingeben
Wie wir aus dem obigen Beispiel sehen können, macht die Verwendung von finally
Block zum Bereinigen von Ressourcen den Code komplexer.
Beachten Sie auch den try… catch
Block im finally
Block? Dies liegt daran, dass ein IOException
auch beim Schließen der BufferedReader
Instanz in diesem finally
Block auftreten kann, sodass sie auch abgefangen und verarbeitet wird.
Die try-with-resources
Anweisung führt eine automatische Ressourcenverwaltung durch . Wir müssen die Ressourcen nicht explizit schließen, da JVM sie automatisch schließt. Dies macht den Code lesbarer und einfacher zu schreiben.
2. Versuchen Sie es mit Ressourcen mit mehreren Ressourcen
Wir können mehr als eine Ressource in der try-with-resources
Anweisung deklarieren, indem wir sie durch ein Semikolon trennen;
Beispiel 3: Versuchen Sie es mit mehreren Ressourcen
import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) )
Wenn dieses Programm ohne Ausnahmen ausgeführt wird, Scanner
liest das Objekt eine Zeile aus der testRead.txt
Datei und schreibt sie in eine neue testWrite.txt
Datei.
Wenn mehrere Deklarationen abgegeben werden, try-with-resources
schließt die Anweisung diese Ressourcen in umgekehrter Reihenfolge. In diesem Beispiel wird das PrintWriter
Objekt zuerst geschlossen und dann das Scanner
Objekt geschlossen.
Java 9 Try-with-Resources-Verbesserung
In Java 7 gibt es eine Einschränkung für die try-with-resources
Anweisung. Die Ressource muss lokal in ihrem Block deklariert werden.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Wenn wir die Ressource in Java 7 außerhalb des Blocks deklariert hätten, hätte dies eine Fehlermeldung generiert.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Um diesen Fehler zu beheben, hat Java 9 die try-with-resources
Anweisung verbessert , sodass die Referenz der Ressource verwendet werden kann, auch wenn sie nicht lokal deklariert ist. Der obige Code wird jetzt ohne Kompilierungsfehler ausgeführt.