I denne vejledning lærer vi om erklæringen om at prøve ressourcer til automatisk at lukke ressourcer.
Den try-with-resources
opgørelse lukker automatisk alle de ressourcer i slutningen af oversigten. En ressource er et objekt, der skal lukkes i slutningen af programmet.
Dens syntaks er:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Som det ses af ovenstående syntaks, erklærer vi try-with-resources
udsagnet af,
- erklære og instantere ressourcen inden for
try
klausulen. - specificere og håndtere alle undtagelser, der kan blive kastet, mens ressourcen lukkes.
Bemærk: Erklæring om ressourcer-med-ressourcer lukker alle de ressourcer, der implementerer grænsefladen AutoCloseable.
Lad os tage et eksempel, der implementerer try-with-resources
udsagnet.
Eksempel 1: prøv-med-ressourcer
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()); ) ) )
Output, hvis test.txt-filen ikke findes.
IOException i prøve-med-ressourcer blok => test.txt (Ingen sådan fil eller bibliotek)
Output, hvis filen test.txt findes.
Indtastning af prøve-ressourcer blok Line => test line
I dette eksempel bruger vi en forekomst af BufferedReader til at læse data fra test.txt
filen.
Erklæring og instantering af BufferedReader inde i try-with-resources
erklæringen sikrer, at dens instans lukkes, uanset om try
udsagnet udfyldes normalt eller kaster en undtagelse.
Hvis der opstår en undtagelse, kan den håndteres ved hjælp af undtagelseshåndteringsblokkene eller kaster-nøgleordet.
Undertrykkede undtagelser
I ovenstående eksempel kan undtagelser kastes fra try-with-resources
udsagnet, når:
- Filen
test.txt
blev ikke fundet. - Lukning af
BufferedReader
objektet.
En undtagelse kan også kastes fra try
blokken, da en fillæsning kan mislykkes af mange grunde til enhver tid.
Hvis undtagelser kastes fra både try
blokken og try-with-resources
udsagnet, undtages undtagelse fra try
blokken, og undtagelse fra try-with-resources
udsagnet undertrykkes.
Henter undertrykkede undtagelser
I Java 7 og senere kan de undertrykkede undtagelser hentes ved at kalde Throwable.getSuppressed()
metoden fra den undtagelse, der er kastet af try
blokken.
Denne metode returnerer en matrix med alle undertrykkede undtagelser. Vi får de undertrykkede undtagelser i catch
blokken.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Fordele ved at bruge prøv-med-ressourcer
Her er fordelene ved at bruge prøve-med-ressourcer:
1. endelig blok ikke krævet for at lukke ressourcen
Før Java 7 introducerede denne funktion, måtte vi bruge finally
blokken for at sikre, at ressourcen er lukket for at undgå ressourceudslip.
Her er et program, der ligner eksempel 1 . Imidlertid har vi i dette program brugt endelig blokering for at lukke ressourcer.
Eksempel 2: Luk ressource ved hjælp af endelig blok
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()); ) ) ) )
Produktion
Indtast forsøg blok Linje => linje fra test.txt-fil Indtast endelig blok
Som vi kan se fra ovenstående eksempel, gør brugen af finally
blok til at rydde op i ressourcer koden mere kompleks.
Bemærk også try… catch
blokken i finally
blokken? Dette skyldes, at en IOException
også kan forekomme under lukning af BufferedReader
forekomsten inde i denne finally
blok, så den også fanges og håndteres.
Det try-with-resources
udsagn gør automatisk ressourcestyring . Vi behøver ikke eksplicit at lukke ressourcerne, da JVM automatisk lukker dem. Dette gør koden mere læselig og lettere at skrive.
2. prøv-med-ressourcer med flere ressourcer
Vi kan erklære mere end én ressource i try-with-resources
erklæringen ved at adskille dem med et semikolon;
Eksempel 3: prøv med flere ressourcer
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()); ) ) ) )
Hvis dette program udføres uden at generere nogen undtagelser, Scanner
læser objektet en linje fra testRead.txt
filen og skriver den i en ny testWrite.txt
fil.
Når der foretages flere erklæringer, try-with-resources
lukker erklæringen disse ressourcer i omvendt rækkefølge. I dette eksempel PrintWriter
lukkes objektet først, og derefter Scanner
lukkes objektet.
Forbedring af Java 9-prøve-med-ressourcer
I Java 7 er der en begrænsning af try-with-resources
udsagnet. Ressourcen skal deklareres lokalt inden for dens blok.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Hvis vi erklærede ressourcen uden for blokken i Java 7, ville den have genereret en fejlmeddelelse.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
For at håndtere denne fejl forbedrede Java 9 try-with-resources
udsagnet, så referencen for ressourcen kan bruges, selvom den ikke er erklæret lokalt. Ovenstående kode udføres nu uden kompileringsfejl.