U ovom uputstvu naučit ćemo o izjavi try-with-resources za automatsko zatvaranje resursa.
try-with-resources
Izjava automatski zatvara sve resurse na kraju izjave. Resurs je objekt koji se zatvara na kraju programa.
Njegova sintaksa je:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Kao što se vidi iz gornje sintakse, izjavu izjavljujemo try-with-resources
,
- deklariranje i instanciranje resursa unutar
try
klauzule. - specificiranje i rukovanje svim iznimkama koje bi mogle nastati prilikom zatvaranja resursa.
Napomena: Izvještaj try-with-resources zatvara sve resurse koji implementiraju sučelje AutoCloseable.
Uzmimo primjer koji provodi try-with-resources
izjavu.
Primjer 1: probajte s resursima
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()); ) ) )
Izlaz ako datoteka test.txt nije pronađena.
IOException u bloku try-with-resources => test.txt (Nema takve datoteke ili direktorija)
Izlaz ako je pronađena datoteka test.txt.
Unos bloka try-with-resources Line => test linija
U ovom primjeru koristimo instancu BufferedReader za čitanje podataka iz test.txt
datoteke.
Deklariranje i instanciranje BufferedReader unutar try-with-resources
izraza osigurava zatvaranje njegove instance bez obzira na to try
završava li se izjava normalno ili baca iznimku.
Ako se dogodi iznimka, njome se može rukovati pomoću blokova za obradu iznimki ili ključne riječi throws.
Potisnute iznimke
U gornjem primjeru, izuzeci se mogu izbaciti iz try-with-resources
izjave kada:
- Datoteka
test.txt
nije pronađena. - Zatvaranje
BufferedReader
objekta.
Iznimka se također može izbaciti iz try
bloka jer čitanje datoteke može u bilo kojem trenutku iz mnogih razloga zakazati.
Ako se izuzmu izuzeci i iz try
bloka i iz try-with-resources
izraza, try
izbacuje se izuzetak iz bloka i try-with-resources
suzbija iznimka iz izraza.
Dohvaćanje potisnutih iznimaka
U Javi 7 i novijim, potisnute iznimke mogu se dobiti pozivanjem Throwable.getSuppressed()
metode iz iznimke koju je izbacio try
blok.
Ova metoda vraća niz svih potisnutih iznimaka. Potisnute iznimke dobivamo u catch
bloku.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Prednosti upotrebe isprobavanja-resursa
Evo prednosti korištenja try-with-resources:
1. konačno blok nije potreban za zatvaranje resursa
Prije nego što je Java 7 predstavila ovu značajku, morali smo koristiti finally
blok kako bismo osigurali zatvaranje resursa kako bismo izbjegli curenje resursa.
Evo programa koji je sličan Primjeru 1 . Međutim, u ovom smo programu koristili konačno blok za zatvaranje resursa.
Primjer 2: Zatvorite resurs pomoću bloka konačno
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()); ) ) ) )
Izlaz
Unos pokušaj bloka Linija => linija iz datoteke test.txt Unos konačnog bloka
Kao što vidimo iz gornjeg primjera, upotreba finally
bloka za čišćenje resursa čini kod složenijim.
Primijetili ste i try… catch
blok u finally
bloku? To je zato što se an IOException
može dogoditi i prilikom zatvaranja BufferedReader
instance unutar ovog finally
bloka, tako da se i on hvata i njime se rukuje.
try-with-resources
Tvrdnja ni automatsko upravljanje resursima . Ne moramo eksplicitno zatvarati resurse jer ih JVM automatski zatvara. To čini kôd čitljivijim i lakšim za pisanje.
2. probajte s resursima s više resursa
U izjavi možemo prijaviti više resursa try-with-resources
razdvajajući ih zarezom;
Primjer 3: pokušajte s više resursa
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()); ) ) ) )
Ako se ovaj program izvrši bez generiranja izuzetaka, Scanner
objekt čita redak iz testRead.txt
datoteke i zapisuje je u novu testWrite.txt
datoteku.
Kada se napravi više deklaracija, try-with-resources
izjava zatvara te resurse obrnutim redoslijedom. U ovom primjeru PrintWriter
objekt se prvo zatvara, a zatim Scanner
zatvara objekt.
Poboljšanje Java 9 s iskustvom
U Javi 7 postoji ograničenje na try-with-resources
izjavu. Izvor treba deklarirati lokalno unutar svog bloka.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Da smo resurs deklarirali izvan bloka u Javi 7, generirao bi poruku o pogrešci.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Da bi se riješila ove pogreške, Java 9 poboljšala je try-with-resources
izjavu tako da se referenca resursa može koristiti čak i ako nije deklarirana lokalno. Gornji kôd sada će se izvršiti bez ikakve pogreške u kompilaciji.