Опит с ресурси на Java (с примери)

В този урок ще научим за инструкцията try-with-resources за автоматично затваряне на ресурси.

В try-with-resourcesизявлението се затварят автоматично, всички ресурси в края на изявлението. Ресурсът е обект, който трябва да бъде затворен в края на програмата.

Синтаксисът му е:

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

Както се вижда от горния синтаксис, ние декларираме try-with-resourcesизявлението от,

  1. деклариране и инстанциране на ресурса в рамките на tryклаузата.
  2. указване и обработка на всички изключения, които могат да се появят при затваряне на ресурса

Забележка: Опитът 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изявлението, така че препратката към ресурса може да се използва, дори ако не е декларирана локално. Горният код сега ще се изпълни без никаква грешка при компилацията.

Интересни статии...