Šajā apmācībā mēs uzzināsim par mēģinājumu ar resursiem automātiski aizvērt resursus.
try-with-resources
Paziņojums automātiski aizver visus resursus beigās paziņojumu. Resurss ir objekts, kas jāaizver programmas beigās.
Tās sintakse ir:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Kā redzams no iepriekš minētās sintakses, paziņojumu try-with-resources
paziņojam,
- resursa deklarēšana un instancēšana
try
klauzulas ietvaros. - norādot un apstrādājot visus izņēmumus, kas varētu rasties, aizverot resursu.
Piezīme . Izmēģinājums ar resursiem aizver visus resursus, kas ievieš saskarni AutoCloseable.
Ņemsim piemēru, kas īsteno try-with-resources
paziņojumu.
1. piemērs: izmēģiniet ar resursiem
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()); ) ) )
Izeja, ja fails test.txt nav atrasts.
IOException izmēģinājuma ar resursiem blokā => test.txt (Nav šāda faila vai direktorija)
Izeja, ja ir atrasts fails test.txt.
Ievadot izmēģinājuma ar resursiem bloku Line => testa rindiņa
Šajā piemērā mēs izmantojam BufferedReader gadījumu, lai nolasītu datus no test.txt
faila.
Paziņojot un izsaucot BufferedReader try-with-resources
paziņojumā, tiek nodrošināts, ka tā eksemplārs ir aizvērts neatkarīgi no tā, vai try
izraksts tiek aizpildīts normāli vai izņēmums.
Ja rodas izņēmums, to var apstrādāt, izmantojot izņēmumu apstrādes blokus vai metienu atslēgvārdu.
Apspiesti izņēmumi
Iepriekš minētajā piemērā izņēmumus var ietvert no try-with-resources
paziņojuma, ja:
- Fails
test.txt
nav atrasts. BufferedReader
Objekta aizvēršana .
Izņēmumu var arī izmest no try
bloka, jo failu lasīšana var neizdoties daudzu iemeslu dēļ jebkurā laikā.
Ja izņēmumi tiek izmesti gan no try
bloka, gan no try-with-resources
paziņojuma, try
tiek izmests izņēmums no bloka un izņēmums no try-with-resources
paziņojuma tiek nomākts.
Nomākto izņēmumu izgūšana
Java 7 un jaunākās versijās nomāktos izņēmumus var iegūt, izsaucot Throwable.getSuppressed()
metodi no try
bloka mestā izņēmuma .
Šī metode atgriež visu nomākto izņēmumu masīvu. catch
Blokā mēs saņemam nomāktos izņēmumus .
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Priekšrocības, izmantojot izmēģināšanas resursus
Šeit ir priekšrocības, izmantojot izmēģināšanas resursus:
1. beidzot bloķēt nav nepieciešams, lai aizvērtu resursu
Pirms Java 7 ieviesa šo funkciju, mums bija jāizmanto finally
bloks, lai pārliecinātos, ka resurss ir aizvērts, lai izvairītos no resursu noplūdes.
Šeit ir programma, kas ir līdzīga 1. piemēram . Tomēr šajā programmā mēs esam izmantojuši beidzot bloķēšanu, lai aizvērtu resursus.
2. piemērs: aizveriet resursu, beidzot bloķējot
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()); ) ) ) )
Rezultāts
Ievadot mēģinājuma bloku Line => line no faila test.txt, beidzot ievadot bloku
Kā redzams no iepriekš minētā piemēra, finally
bloka izmantošana resursu attīrīšanai padara kodu sarežģītāku.
Vai pamanāt arī try… catch
bloku finally
blokā? Tas notiek tāpēc, ka IOException
var rasties arī, aizverot BufferedReader
instanci šī finally
bloka iekšienē, tāpēc tas tiek arī noķerts un apstrādāts.
try-with-resources
Paziņojums nav automātisku resursu pārvaldību . Mums nav skaidri jāaizver resursi, jo JVM tos automātiski aizver. Tas padara kodu vieglāk lasāmu un vieglāk rakstāmu.
2. izmēģināt ar resursiem ar vairākiem resursiem
Mēs varam deklarēt vairāk nekā vienu resursu try-with-resources
paziņojumā, atdalot tos ar semikolu;
3. piemērs: mēģiniet ar vairākiem resursiem
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()); ) ) ) )
Ja šī programma tiek izpildīta, neradot nekādus izņēmumus, Scanner
objekts nolasa testRead.txt
faila rindiņu un ieraksta to jaunā testWrite.txt
failā.
Kad tiek veiktas vairākas deklarācijas, try-with-resources
paziņojums aizver šos resursus apgrieztā secībā. Šajā piemērā PrintWriter
objekts vispirms tiek aizvērts un pēc tam Scanner
objekts tiek aizvērts.
Java 9 izmēģināšanas ar resursiem uzlabošana
Programmā Java 7 try-with-resources
apgalvojumam ir ierobežojums . Resurss ir jādeklarē lokāli tā blokā.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Ja mēs deklarētu resursu ārpus Java 7 bloka, tas būtu ģenerējis kļūdas ziņojumu.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Lai novērstu šo kļūdu, Java 9 uzlaboja try-with-resources
paziņojumu, lai resursa atsauci varētu izmantot pat tad, ja tā nav deklarēta lokāli. Iepriekš minētais kods tiks izpildīts bez kompilācijas kļūdas.