V tomto tutoriále sa dozvieme o príkaze try-with-resources na automatické zatváranie zdrojov.
try-with-resources
Vyhlásenie automaticky uzavrie všetky prostriedky na konci príkazu. Zdroj je objekt, ktorý sa má uzavrieť na konci programu.
Jeho syntax je:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Ako je zrejmé z vyššie uvedenej syntaxe, vyhlásenie deklarujeme try-with-resources
pomocou,
- deklarovanie a vytvorenie inštancie prostriedku v rámci
try
doložky. - špecifikovanie a spracovanie všetkých výnimiek, ktoré by mohli byť vyvolané pri zatváraní prostriedku.
Poznámka: Príkaz try-with-resources zatvára všetky prostriedky, ktoré implementujú rozhranie AutoCloseable.
Zoberme si príklad, ktorý implementuje try-with-resources
vyhlásenie.
Prí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, ak sa súbor test.txt nenájde.
IOException in try-with-resources block => test.txt (Žiadny takýto súbor alebo adresár)
Výstup, ak sa nájde súbor test.txt.
Vstup do bloku try-with-resources Line => testovací riadok
V tomto príklade používame na načítanie údajov zo test.txt
súboru inštanciu BufferedReader .
Deklarovanie a vytvorenie inštancie BufferedReader vo vnútri try-with-resources
príkazu zabezpečí, že jeho inštancia je uzavretá bez ohľadu na to, či sa try
príkaz dokončí normálne alebo vyvolá výnimku.
Ak dôjde k výnimke, je možné ju vyriešiť pomocou blokov na spracovanie výnimiek alebo kľúčového slova throws.
Potlačené výnimky
Vo vyššie uvedenom príklade možno z try-with-resources
vyhlásenia vyvolať výnimky, keď:
- Súbor
test.txt
sa nenašiel. - Zatvorenie
BufferedReader
objektu.
Z try
bloku môže byť vyvolaná aj výnimka, pretože načítanie súboru môže kedykoľvek zlyhať z mnohých dôvodov.
Ak sú výnimky vyvolané z try
bloku aj z try-with-resources
príkazu, výnimka z try
bloku je vyvolaná a výnimka z try-with-resources
príkazu je potlačená.
Načítanie potlačených výnimiek
V prostredí Java 7 a novších je možné potlačené výnimky získať zavolaním Throwable.getSuppressed()
metódy z výnimky vyvolanej try
blokom.
Táto metóda vráti pole všetkých potlačených výnimiek. Dostaneme potlačené výnimky v catch
bloku.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Výhody využívania zdrojov vyskúšania
Výhody použitia try-with-resources sú tieto:
1. konečne blokovanie nie je potrebné na zatvorenie zdroja
Predtým, ako Java 7 predstavila túto funkciu, museli sme použiť finally
blok, aby sme sa ubezpečili, že zdroj je zatvorený, aby sa zabránilo úniku zdrojov.
Tu je program podobný príkladu 1 . V tomto programe sme však použili konečne block na zatvorenie zdrojov.
Príklad 2: Zatvorte zdroj pomocou konečne bloku
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ýkon
Zadanie bloku try Line => riadok zo súboru test.txt Zadanie bloku konečne
Ako vidíme z vyššie uvedeného príkladu, použitie finally
bloku na vyčistenie zdrojov robí kód zložitejším.
Všimli ste si try… catch
blok aj v finally
bloku? Je to tak preto, lebo sa IOException
môže vyskytnúť aj pri zatváraní BufferedReader
inštancie vo vnútri tohto finally
bloku, takže sa tiež zachytáva a manipuluje sa s ňou.
Príkaz try-with-resources
vykonáva automatickú správu zdrojov . Zdroje nemusíme výslovne zatvárať, pretože JVM ich automaticky zatvára. Vďaka tomu je kód čitateľnejší a ľahšie sa píše.
2. vyskúšajte zdroje s viacerými prostriedkami
Vo vyhlásení môžeme deklarovať viac ako jeden prostriedok tak, že try-with-resources
ich oddelíme bodkočiarkou;
Príklad 3: Vyskúšajte viac zdrojov
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()); ) ) ) )
Ak sa tento program spustí bez generovania akýchkoľvek výnimiek, Scanner
objekt načíta riadok zo testRead.txt
súboru a zapíše ho do nového testWrite.txt
súboru.
Keď dôjde k niekoľkým vyhláseniam, try-with-resources
príkaz zatvorí tieto prostriedky v opačnom poradí. V tomto príklade PrintWriter
je najskôr uzavretý objekt a potom je Scanner
objekt zatvorený.
Vylepšenie pokusu s prostriedkami Java 9
V prostredí Java 7 je vyhlásenie obmedzené try-with-resources
. Zdroj je potrebné deklarovať lokálne v rámci jeho bloku.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Keby sme zdroj deklarovali mimo blok v Jave 7, vygenerovalo by to chybové hlásenie.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Za účelom riešenia tejto chyby Java 9 vylepšila try-with-resources
vyhlásenie tak, aby bolo možné použiť referenciu zdroja, aj keď nie je deklarovaná lokálne. Vyššie uvedený kód sa teraz vykoná bez akejkoľvek chyby kompilácie.