В этом руководстве мы узнаем об операторе 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 => test.txt (нет такого файла или каталога)
Вывести, если файл test.txt найден.
Ввод блока try-with-resources Line => test 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
Вот преимущества использования try-with-resources:
1. блок finally не требуется для закрытия ресурса
До того, как в Java 7 появилась эта функция, мы должны были использовать finally
блок, чтобы гарантировать, что ресурс закрыт, чтобы избежать утечки ресурсов.
Вот программа, похожая на Пример 1 . Однако в этой программе мы использовали блок finally для закрытия ресурсов.
Пример 2: закрыть ресурс с помощью блока 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()); ) ) ) )
Вывод
Ввод блока try Line => строка из файла test.txt Ввод блока finally
Как видно из приведенного выше примера, использование finally
блока для очистки ресурсов усложняет код.
Обратите внимание на try… catch
блок в finally
блоке? Это связано с тем, что an 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
оператор, так что ссылку на ресурс можно использовать, даже если он не объявлен локально. Приведенный выше код теперь будет выполняться без ошибок компиляции.