В този урок ще научим за инструкцията try-with-resources за автоматично затваряне на ресурси.
В try-with-resourcesизявлението се затварят автоматично, всички ресурси в края на изявлението. Ресурсът е обект, който трябва да бъде затворен в края на програмата.
Синтаксисът му е:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Както се вижда от горния синтаксис, ние декларираме try-with-resourcesизявлението от,
- деклариране и инстанциране на ресурса в рамките на
tryклаузата. - указване и обработка на всички изключения, които могат да се появят при затваряне на ресурса
Забележка: Опитът try-with-resources затваря всички ресурси, които реализират интерфейса AutoCloseable.
Нека вземем пример, който реализира try-with-resourcesизявлението.
Пример 1: опитайте с ресурси
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()); ) ) )
Изход, ако файлът test.txt не е намерен.
IOException в try-with-resources block => test.txt (Няма такъв файл или директория)
Изход, ако е намерен файл test.txt.
Въвеждане на блок try-with-resources Line => тестов ред
В този пример използваме екземпляр на BufferedReader за четене на данни от test.txtфайла.
Декларирането и създаването на екземпляр на BufferedReader вътре в try-with-resourcesизраза гарантира, че неговият екземпляр е затворен, независимо дали tryизразът завършва нормално или изхвърля изключение.
Ако възникне изключение, то може да бъде обработено с помощта на блокове за обработка на изключения или ключовата дума throws.
Потиснати изключения
В горния пример изключенията могат да бъдат изхвърлени от try-with-resourcesизявлението, когато:
- Файлът
test.txtне е намерен. - Затваряне на
BufferedReaderобекта.
Изключение може да бъде хвърлено и от tryблока, тъй като четенето на файл може да се провали по много причини по всяко време.
Ако се хвърлят изключения както от tryблока, така и от try-with-resourcesоператора, изключението от tryблока се изхвърля и изключение от try-with-resourcesизраза се потиска.
Извличане на потиснати изключения
В Java 7 и по-късно потиснатите изключения могат да бъдат извлечени чрез извикване на Throwable.getSuppressed()метода от изключението, хвърлено от tryблока.
Този метод връща масив от всички потиснати изключения. Получаваме потиснатите изключения в catchблока.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Предимства на използването на опит с ресурси
Ето предимствата на използването на try-with-resources:
1. накрая не се изисква блок за затваряне на ресурса
Преди Java 7 да представи тази функция, трябваше да използваме finallyблока, за да гарантираме, че ресурсът е затворен, за да се избегнат изтичания на ресурси.
Ето програма, подобна на Пример 1 . Въпреки това, в тази програма, ние използвахме окончателно блок за затваряне на ресурси.
Пример 2: Затворете ресурса с помощта на блок block
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()); ) ) ) )
Изход
Въвеждане на блок за опити Line => ред от файл test.txt Въвеждане на окончателно блок
Както можем да видим от горния пример, използването на finallyблок за почистване на ресурси прави кода по-сложен.
Забелязвате ли и try… catchблока в finallyблока? Това е така, защото IOExceptionможе да възникне и при затваряне на BufferedReaderекземпляра вътре в този finallyблок, така че той също се улавя и обработва.
В try-with-resourcesизявлението прави автоматично управление на ресурсите . Не е необходимо изрично да затваряме ресурсите, тъй като JVM автоматично ги затваря. Това прави кода по-четлив и по-лесен за писане.
2. опитайте с ресурси с множество ресурси
Можем да декларираме повече от един ресурс в try-with-resourcesизявлението, като ги разделяме с точка и запетая;
Пример 3: опитайте с множество ресурси
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()); ) ) ) )
Ако тази програма се изпълнява, без да генерира изключения, Scannerобектът чете ред от testRead.txtфайла и го записва в нов testWrite.txtфайл.
Когато са направени множество декларации, try-with-resourcesизразът затваря тези ресурси в обратен ред. В този пример PrintWriterобектът се затваря първо и след това Scannerобектът се затваря.
Java 9 подобряване на опит с ресурси
В Java 7 има ограничение за try-with-resourcesизявлението. Ресурсът трябва да бъде деклариран локално в рамките на своя блок.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Ако декларирахме ресурса извън блока в Java 7, той би генерирал съобщение за грешка.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
За да се справи с тази грешка, Java 9 подобри try-with-resourcesизявлението, така че препратката към ресурса може да се използва, дори ако не е декларирана локално. Горният код сега ще се изпълни без никаква грешка при компилацията.








