Ebben az oktatóanyagban megismerkedhetünk a try-with-resources utasítással az erőforrások automatikus bezárásához.
Az try-with-resources
utasítás automatikusan bezárja az összes erőforrást a kimutatás végén. Az erőforrás a program végén bezárandó objektum.
Szintaxisa:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Amint a fenti szintaxisból látható, az try-with-resources
állítást a
- az erőforrás deklarálása és példányosítása a
try
záradékban. - az erőforrás bezárása során felmerülő összes kivétel meghatározása és kezelése.
Megjegyzés: A try-with-resources utasítás bezárja az összes erőforrást, amely megvalósítja az AutoCloseable felületet.
Vegyünk egy példát, amely megvalósítja az try-with-resources
állítást.
1. példa: próbáld ki az erőforrásokat
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()); ) ) )
Kimenet, ha a test.txt fájl nem található.
IOException a try-with-resources blokkban => test.txt (Nincs ilyen fájl vagy könyvtár)
Kimenet, ha a test.txt fájl megtalálható.
Belépés a try-with-resources blokkba Line => teszt sor
Ebben a példában a BufferedReader példányát használjuk az adatok kiolvasásához a test.txt
fájlból.
A BufferedReader try-with-resources
utasításban történő deklarálása és példányosítása biztosítja a példány bezárását, függetlenül attól, hogy az try
utasítás normálisan teljesül- e, vagy kivételt hoz.
Kivétel esetén a kivételkezelő blokkok vagy a dob kulcsszó segítségével kezelhető.
Elnyomott kivételek
A fenti példában kivételek vethetők ki az try-with-resources
utasításból, ha:
- A fájl
test.txt
nem található. - Az
BufferedReader
objektum bezárása .
Kivételt lehet dobni a try
blokkból is, mivel a fájlolvasás sok okból bármikor meghiúsulhat.
Ha a try
blokkból és az try-with-resources
utasításból is kivételt try
dobnak, akkor a blokkból származó kivételt dobják, és az try-with-resources
utasítás kivételét elnyomják.
Letiltott kivételek lekérése
A Java 7 és újabb verzióiban az elnyomott kivételek a Throwable.getSuppressed()
metódus meghívásával lekérhetők a try
blokk által dobott kivételből .
Ez a módszer az összes elfojtott kivétel tömbjét adja vissza. Az elnyomott kivételeket a catch
blokkban kapjuk meg .
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
A try-with-resources használatának előnyei
Íme a try-with-resources használatának előnyei:
1. végül az erőforrás bezárásához nem szükséges blokk
Mielőtt a Java 7 bevezette ezt a funkciót, a finally
blokkot kellett használnunk annak biztosítására, hogy az erőforrás zárva legyen az erőforrás szivárgásának elkerülése érdekében.
Itt van az 1. példához hasonló program . Ebben a programban azonban a blokkolással az erőforrások bezárását használtuk.
2. példa: Az erőforrás bezárása a végső blokk használatával
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()); ) ) ) )
Kimenet
Belépés a próbablokkba Line => sor a test.txt fájlból. Végül belépés a blokkba
Amint a fenti példából láthatjuk, a finally
blokk használata az erőforrások tisztítására összetettebbé teszi a kódot.
Figyelje meg a try… catch
blokkot is a finally
blokkban? Ennek az az oka, hogy a blokk belsejében IOException
lévő BufferedReader
példány bezárásakor is előfordulhat, finally
így azt is elkapják és kezelik.
Az try-with-resources
utasítás automatikus erőforrás-kezelést végez . Nem kell kifejezetten bezárnunk az erőforrásokat, mivel a JVM automatikusan bezárja azokat. Ezáltal a kód olvashatóbbá és könnyebben írhatóvá válik.
2. próbálkozzon erőforrásokkal több erőforrással
Egynél több erőforrást deklarálhatunk az try-with-resources
utasításban pontosvesszővel elválasztva;
3. példa: próbáljon több erőforrással
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()); ) ) ) )
Ha ez a program kivételek generálása nélkül hajt végre, az Scanner
objektum felolvas egy sort a testRead.txt
fájlból és új testWrite.txt
fájlba írja .
Több deklaráció elkészítésekor az try-with-resources
utasítás fordított sorrendben zárja le ezeket az erőforrásokat. Ebben a példában PrintWriter
először az objektum záródik, majd az Scanner
objektum záródik.
Java 9 próbálja erőforrásokkal javítás
A Java 7-ben van egy korlátozás az try-with-resources
utasításra. Az erőforrást helyileg kell deklarálni a blokkon belül.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Ha az erőforrást a Java 7 blokkon kívülre deklaráltuk, akkor hibaüzenetet generált volna.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Ennek a hibának a kezelésére a Java 9 továbbfejlesztette az try-with-resources
utasítást, így az erőforrás hivatkozása akkor is használható, ha azt nem helyileg deklarálták. A fenti kód fordítási hiba nélkül fog végrehajtani.