V tej vadnici bomo spoznali izjavo »poskusi z viri« za samodejno zapiranje virov.
try-with-resources
Izjava samodejno zapre vse vire, na koncu stavka. Vir je predmet, ki ga je treba zapreti na koncu programa.
Njegova sintaksa je:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Kot je razvidno iz zgornje sintakse, trdimo try-with-resources
, da
- razglasitev in instanciranje vira znotraj
try
klavzule. - določanje in obravnavanje vseh izjem, ki bi lahko nastale med zapiranjem vira.
Opomba: Stavek try-with-resources zapre vse vire, ki izvajajo vmesnik AutoCloseable.
Vzemimo primer, ki izvaja try-with-resources
izjavo.
Primer 1: poskusi z viri
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()); ) ) )
Izpis, če datoteke test.txt ni mogoče najti.
IOException v bloku try-with-resources => test.txt (ni take datoteke ali imenika)
Izpis, če je najdena datoteka test.txt.
Vnos bloka try-with-resources Line => test line
V tem primeru za branje podatkov iz test.txt
datoteke uporabljamo primerek BufferedReader .
Deklariranje in instanciranje BufferedReader znotraj try-with-resources
stavka zagotavlja, da je njegov primerek zaprt, ne glede na to, ali try
stavek dokonča normalno ali vrže izjemo.
Če pride do izjeme, jo je mogoče obdelati z uporabo blokov za obdelavo izjem in s ključno besedo throws.
Potlačene izjeme
V zgornjem primeru lahko iz try-with-resources
stavka vržemo izjeme, kadar:
- Datoteke
test.txt
ni mogoče najti. - Zapiranje
BufferedReader
predmeta.
Iz try
bloka lahko vržemo tudi izjemo, saj lahko branje datoteke kadar koli iz več razlogov ne uspe.
Če se iz try
bloka in try-with-resources
stavka vržejo izjeme, se vrže izjema iz try
bloka in izjema iz try-with-resources
stavka se zatre.
Pridobivanje potlačenih izjem
V Javi 7 in novejših različicah je mogoče potisnjene izjeme pridobiti s klicanjem Throwable.getSuppressed()
metode iz izjeme, ki jo je vrgel try
blok.
Ta metoda vrne niz vseh potlačenih izjem. V catch
bloku dobimo zatrte izjeme .
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Prednosti uporabe poskusi z viri
Tu so prednosti uporabe preizkusi z viri:
1. dokončno blokiranje ni potrebno za zapiranje vira
Preden je Java 7 predstavila to funkcijo, smo morali z finally
blokom zagotoviti, da je vir zaprt, da se izognemo uhajanju virov.
Tu je program, ki je podoben primeru 1 . Vendar smo v tem programu uporabili dokončno blok za zapiranje virov.
Primer 2: Zaprite vir s pomočjo končnega bloka
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()); ) ) ) )
Izhod
Vnos poskusni blok Line => vrstica iz datoteke test.txt Vnos končnega bloka
Kot lahko vidimo iz zgornjega primera, uporaba finally
bloka za čiščenje virov naredi kodo bolj zapleteno.
Ste opazili tudi try… catch
blok v finally
bloku? Razlog za to je, da IOException
lahko pride tudi do zapiranja BufferedReader
primerka znotraj tega finally
bloka, zato je tudi ujet in obdelan.
try-with-resources
Izjava ne avtomatsko upravljanje virov . Virov nam ni treba izrecno zapreti, saj jih JVM samodejno zapre. Tako je koda bolj berljiva in lažja za pisanje.
2. poskusite z viri z več viri
V izjavi lahko prijavimo več kot en vir, tako da try-with-resources
jih ločimo s podpičjem;
3. primer: poskusite z več viri
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()); ) ) ) )
Če se ta program zažene brez izjem, Scanner
objekt prebere vrstico iz testRead.txt
datoteke in jo zapiše v novo testWrite.txt
datoteko.
Ko je podanih več izjav, try-with-resources
stavek zapre te vire v obratnem vrstnem redu. V tem primeru se PrintWriter
objekt najprej zapre, nato pa Scanner
objekt.
Izboljšava Java 9 s preizkusi virov
V Javi 7 obstaja omejitev try-with-resources
stavka. Vir je treba prijaviti lokalno v svojem bloku.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Če bi vir razglasili zunaj bloka v Javi 7, bi ustvaril sporočilo o napaki.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Da bi rešila to napako, je Java 9 izboljšala try-with-resources
stavek, tako da je mogoče uporabiti sklic na vir, tudi če ni deklariran lokalno. Zgornja koda se bo zdaj izvajala brez napak pri prevajanju.