In deze zelfstudie leren we over de try-with-resources-instructie om bronnen automatisch te sluiten.
De try-with-resources
instructie sluit automatisch alle bronnen aan het einde van de instructie. Een bron is een object dat aan het einde van het programma moet worden gesloten.
De syntaxis is:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Zoals blijkt uit de bovenstaande syntaxis, verklaren we de try-with-resources
verklaring door,
- declareren en instantiëren van de resource binnen de
try
clausule. - het specificeren en afhandelen van alle uitzonderingen die kunnen optreden bij het sluiten van de bron.
Opmerking: de instructie try-with-resources sluit alle bronnen die de AutoCloseable-interface implementeren.
Laten we een voorbeeld nemen dat de try-with-resources
verklaring implementeert .
Voorbeeld 1: try-with-resources
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()); ) ) )
Voer uit als het test.txt-bestand niet wordt gevonden.
IOException in try-with-resources block => test.txt (geen bestand of directory)
Voer uit als het bestand test.txt wordt gevonden.
Het try-with-resources-blok invoeren Line => test line
In dit voorbeeld gebruiken we een instantie van BufferedReader om gegevens uit het test.txt
bestand te lezen .
Het declareren en instantiëren van de BufferedReader binnen de try-with-resources
instructie zorgt ervoor dat de instantie wordt gesloten, ongeacht of de try
instructie normaal wordt voltooid of een uitzondering genereert.
Als er een uitzondering optreedt, kan deze worden afgehandeld met behulp van de uitzonderingsafhandelingsblokken of het worp-sleutelwoord.
Onderdrukte uitzonderingen
In het bovenstaande voorbeeld kunnen uitzonderingen worden gegenereerd op de try-with-resources
instructie als:
- Het bestand
test.txt
is niet gevonden. - Het
BufferedReader
object sluiten.
Er kan ook een uitzondering worden gegenereerd vanuit het try
blok, omdat het lezen van een bestand om vele redenen op elk moment kan mislukken.
Als er uitzonderingen worden gegenereerd door zowel het try
blok als de try-with-resources
instructie, wordt de uitzondering van het try
blok gegenereerd en wordt de uitzondering op de try-with-resources
instructie onderdrukt.
Onderdrukte uitzonderingen ophalen
In Java 7 en hoger kunnen de onderdrukte uitzonderingen worden opgehaald door de Throwable.getSuppressed()
methode aan te roepen vanuit de uitzondering die door het try
blok wordt gegenereerd .
Deze methode retourneert een array met alle onderdrukte uitzonderingen. We krijgen de onderdrukte uitzonderingen in het catch
blok.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Voordelen van het gebruik van try-with-resources
Dit zijn de voordelen van het gebruik van try-with-resources:
1. Eindelijk blok niet vereist om de bron te sluiten
Voordat Java 7 deze functie introduceerde, moesten we het finally
blok gebruiken om ervoor te zorgen dat de bron gesloten is om lekken van bronnen te voorkomen.
Hier is een programma dat vergelijkbaar is met Voorbeeld 1 . In dit programma hebben we echter eindelijk block gebruikt om bronnen te sluiten.
Voorbeeld 2: resource sluiten met behulp van final 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()); ) ) ) )
Uitvoer
Het invoeren van try block Line => regel uit het test.txt-bestand. Eindelijk blok invoeren
Zoals we in het bovenstaande voorbeeld kunnen zien, maakt het gebruik van finally
block om bronnen op te schonen de code complexer.
Let ook op het try… catch
blok in het finally
blok? Dit komt omdat IOException
er ook een kan optreden tijdens het sluiten van de BufferedReader
instantie binnen dit finally
blok, zodat deze ook wordt opgevangen en afgehandeld.
De try-with-resources
verklaring voert automatisch middelenbeheer uit . We hoeven de bronnen niet expliciet te sluiten omdat JVM ze automatisch sluit. Dit maakt de code beter leesbaar en gemakkelijker te schrijven.
2. probeer-met-bronnen met meerdere bronnen
We kunnen meer dan één bron in de try-with-resources
instructie declareren door ze te scheiden met een puntkomma;
Voorbeeld 3: probeer met meerdere bronnen
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()); ) ) ) )
Als dit programma wordt uitgevoerd zonder uitzonderingen te genereren, Scanner
leest het object een regel uit het testRead.txt
bestand en schrijft het in een nieuw testWrite.txt
bestand.
Als er meerdere aangiften zijn gedaan, try-with-resources
sluit de verklaring deze bronnen in omgekeerde volgorde. In dit voorbeeld wordt het PrintWriter
object eerst gesloten en daarna wordt het Scanner
object gesloten.
Verbetering van Java 9-try-with-resources
In Java 7 is er een beperking op de try-with-resources
instructie. De bron moet lokaal binnen zijn blok worden gedeclareerd.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Als we de bron buiten het blok in Java 7 hadden gedeclareerd, zou dit een foutmelding hebben gegenereerd.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Om deze fout te verhelpen, heeft Java 9 de try-with-resources
instructie verbeterd zodat de referentie van de bron kan worden gebruikt, zelfs als deze niet lokaal wordt gedeclareerd. De bovenstaande code wordt nu uitgevoerd zonder enige compilatiefout.