English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Основной учебник Java

Java управление потоком

Java массив

Java Ориентированность на объекты (I)

Java Ориентированность на объекты (II)

Java Ориентированность на объекты (III)

Обработка исключений Java

Java Списки (List)

Java Queue (очередь)

Java Map-сборники

Java Set-сборники

Java Ввод/вывод (I/O)

Java Reader/Writer

Другие темы Java

try-with-resources Java

В этом руководстве мы изучим предложение try-with-resources для автоматического закрытия ресурсов.

Предложение try-with-resources автоматически закрывает все ресурсы в конце предложения. Ресурсы - это объекты, которые необходимо закрыть в конце программы.

Его грамматика такая:

try(resource declaration) {
  // использование ресурса
}
  // блок catch
{}

Из грамматики可以看出, мы определяем предложение try-with-resources следующим образом:

  1. Декларируйте и инстанцируйте ресурсы в предложении try.

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

Примечание:Предложение try-with-resources закрывает все ресурсы, реализующие интерфейс AutoCloseable.

Давайте рассмотрим пример реализации предложения try-with-resources.

Пример 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);
      {}
    }
      System.out.println("IOException в блоке try =>" + e.getMessage());
    {}
  {}
{}

Если файл test.txt не найден, выводится.

IOException в блоке try-with-resources => test.txt (No such file or directory)

Если файл test.txt найден, выводится.

Вход в блок try-with-resources
Строка => строка test

В этом примере мы используем экземпляр BufferedReader для чтения данных из файла test.txt.

Декларация и инстанцирование BufferedReader в предложении try-with-resources гарантирует закрытие его экземпляра, независимо от того, завершается ли предложение trynormally или инициируется исключение.

Если возникает исключение, можно использовать блок обработки исключений илиключевое слово 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.length; i++) {
    System.out.println("Suppressed exception=>" + suppressedExceptions[i]);
  {}
{}

Преимущества использования try-with-resources

Преимущества использования try-with-resources:

1. Блок finally не требует закрытия ресурсов

До того как эта функция была введена в Java 7,我们必须使用finally блок, чтобы обеспечить закрытие ресурсов и избежать утечки ресурсов.

Это похоже наПример программыНо в этом программном обеспечении мы используем блок finally для закрытия ресурсов.

Пример 2: использование блока finally для закрытия ресурсов

import java.io.*;
class Main {
  public static void main(String[] args) {
    BufferedReader br = null;
    String line;
    try {
      System.out.println("Вход в блок try");
      br = new BufferedReader(new FileReader("test.txt"));
      while ((line = br.readLine()) != null) {
        System.out.println("Line =>" + line);
      {}
    }
      System.out.println("IOException в блоке try =>" + e.getMessage());
    } finally {
      System.out.println("Вход в finally блок");
      try {
        if (br != null) {
          br.close();
        {}
      }
        System.out.println("IOException в finally блоке =>" + e.getMessage());
      {}
    {}
  {}
{}

Результат вывода

Вход в блок try
Line => line из файла test.txt
Вход в finally блок

Из上面的 примера можно看出, что использование блока finally для очистки ресурсов делает код более сложным.

Вы заметили блок try ... catch в finally? Это потому, что при закрытии этого экземпляра BufferedReader в finally блоке также может произойти IOException, поэтому его также необходимо捕获 и обработать.

Выполнение предложения try-with-resourcesАвтоматическое управление ресурсами. Мы не нуждаемся в явном закрытии ресурсов, так как JVM автоматически закроет их. Это делает код более читаемым и легким для написания.

2. try-with-resources несколько ресурсов

Мы можем использовать точку с запятой для разделения нескольких ресурсов в 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());
      {}
    {}
  {}
{}

Если при выполнении программы не было создано żadных исключений, объект Scanner считывает строку из файла testRead.txt и записывает ее в новый файл testWrite.txt.

При нескольких объявлениях try-with-resources закрывает эти ресурсы в обратном порядке. В данном примере сначала закрывается объект PrintWriter, затем объект Scanner.

Улучшение try-with-resources в Java 9

В Java 7 оператор try-with-resources имеет ограничение. Ресурс должен быть локально объявлен в блоке.

try (Scanner scanner = new Scanner(new File("testRead.txt"))) {
  // code
{}

Если мы в Java 7 DECLARE ресурс вне блока, то будет выдаваться сообщение об ошибке.

Scanner scanner = new Scanner(new File("testRead.txt"));
try (scanner) {
  // code
{}

Чтобы решить эту ошибку, Java 9 улучшил этот оператор try-with-resources, чтобы можно было использовать его, даже если ресурс не был локально объявлен. В настоящее время код будет выполняться, и не будет выдаваться никаких компиляционных ошибок.