Java try-with-resources (s příklady)

V tomto kurzu se dozvíme o příkazu try-with-resources k automatickému zavření prostředků.

Příkaz try-with-resourcesna konci výpisu automaticky zavře všechny prostředky. Prostředek je objekt, který má být uzavřen na konci programu.

Jeho syntaxe je:

 try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block ) 

Jak je vidět z výše uvedené syntaxe, deklarujeme try-with-resourcesprohlášení,

  1. deklarace a vytvoření instance prostředku v tryklauzuli.
  2. určení a zpracování všech výjimek, které mohou být vyvolány při zavírání prostředku.

Poznámka: Příkaz try-with-resources zavře všechny prostředky, které implementují rozhraní AutoCloseable.

Vezměme si příklad, který try-with-resourcesprohlášení implementuje .

Příklad 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()); ) ) ) 

Výstup, pokud soubor test.txt nebyl nalezen.

 IOException in try-with-resources block => test.txt (Žádný takový soubor nebo adresář) 

Výstup, pokud bude nalezen soubor test.txt.

 Vstup do bloku try-with-resources Line => testovací řádek 

V tomto příkladu používáme instanci BufferedReader ke čtení dat ze test.txtsouboru.

Deklarace a vytvoření instance BufferedReader uvnitř try-with-resourcespříkazu zajišťuje, že jeho instance je uzavřena bez ohledu na to, zda se trypříkaz dokončí normálně nebo vyvolá výjimku.Declaring and instantiating the BufferedReader inside the statement ensures that its instance is closed depending on whether the statement completes normal or throws an exception.

Pokud dojde k výjimce, lze ji zpracovat pomocí bloků zpracování výjimek nebo klíčového slova throws.

Potlačené výjimky

Ve výše uvedeném příkladu lze z try-with-resourcespříkazu vyvolat výjimky, když:

  • Soubor test.txtnebyl nalezen.
  • Uzavření BufferedReaderobjektu.

Výjimku lze také vyvolat z trybloku, protože čtení souboru může kdykoli selhat z mnoha důvodů.

Pokud jsou vyvolány výjimky z trybloku i z try-with-resourcespříkazu, tryje vyvolána výjimka z bloku a výjimka z try-with-resourcespříkazu je potlačena.

Načítání potlačených výjimek

V Javě 7 a novějších potlačené výjimky lze načíst voláním Throwable.getSuppressed()metody z výjimky vyvolané tryblokem.

Tato metoda vrací pole všech potlačených výjimek. Dostaneme potlačené výjimky v catchbloku.

 catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) ) 

Výhody použití try-with-resources

Tady jsou výhody používání try-with-resources:

1. konečně blokování není nutné k uzavření zdroje

Než Java 7 představila tuto funkci, museli jsme pomocí finallybloku zajistit, aby byl prostředek uzavřen, aby nedocházelo k únikům prostředků.

Zde je program podobný příkladu 1 . V tomto programu jsme však použili nakonec block k uzavření prostředků.

Příklad 2: Zavřete zdroj pomocí bloku finally

 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()); ) ) ) ) 

Výstup

 Zadání bloku try Řádek => řádek ze souboru test.txt Zadání bloku konečně 

Jak vidíme z výše uvedeného příkladu, díky použití finallybloku k vyčištění prostředků je kód složitější.

Všimněte si také try… catchbloku v finallybloku? Důvodem je, že IOExceptionmůže dojít také při zavírání BufferedReaderinstance uvnitř tohoto finallybloku, takže je také zachycen a zpracován.

Příkaz try-with-resourcesprovádí automatickou správu prostředků . Prostředky nemusíme explicitně zavírat, protože JVM je automaticky zavírá. Díky tomu je kód čitelnější a snazší na psaní.

2. vyzkoušet zdroje s více prostředky

V try-with-resourcespříkazu můžeme deklarovat více než jeden prostředek tak, že je oddělíme středníkem;

Příklad 3: Vyzkoušejte více zdrojů

 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()); ) ) ) ) 

Pokud se tento program spustí bez generování výjimek, Scannerobjekt načte řádek ze testRead.txtsouboru a zapíše jej do nového testWrite.txtsouboru.

Když je provedeno více deklarací, try-with-resourcespříkaz zavře tyto prostředky v opačném pořadí. V tomto příkladu je PrintWriterobjekt nejprve uzavřen a poté je Scannerobjekt uzavřen.

Vylepšení vyzkoušení prostředků v prostředí Java 9

V prostředí Java 7 existuje omezení try-with-resourcespříkazu. Zdroj musí být deklarován lokálně v rámci svého bloku.

 try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code ) 

Pokud bychom prostředek deklarovali mimo blok v Javě 7, vygeneroval by chybovou zprávu.

 Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code ) 

Pro řešení této chyby Java 9 vylepšila try-with-resourcespříkaz tak, aby bylo možné použít odkaz na prostředek, i když není deklarován lokálně. Výše uvedený kód se nyní spustí bez jakékoli chyby kompilace.

Zajímavé články...