English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В этом руководстве мы изучим предложение try-with-resources для автоматического закрытия ресурсов.
Предложение try-with-resources автоматически закрывает все ресурсы в конце предложения. Ресурсы - это объекты, которые необходимо закрыть в конце программы.
Его грамматика такая:
try(resource declaration) { // использование ресурса } // блок catch {}
Из грамматики可以看出, мы определяем предложение try-with-resources следующим образом:
Декларируйте и инстанцируйте ресурсы в предложении try.
Определите и обработайте все исключения, которые могут быть инициированы при закрытии ресурсов.
Примечание:Предложение try-with-resources закрывает все ресурсы, реализующие интерфейс AutoCloseable.
Давайте рассмотрим пример реализации предложения 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:
До того как эта функция была введена в Java 7,我们必须使用finally блок, чтобы обеспечить закрытие ресурсов и избежать утечки ресурсов.
Это похоже наПример программыНо в этом программном обеспечении мы используем блок 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 автоматически закроет их. Это делает код более читаемым и легким для написания.
Мы можем использовать точку с запятой для разделения нескольких ресурсов в try-with-resources, чтобы объявить несколько ресурсов в одном предложении;
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.
В 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, чтобы можно было использовать его, даже если ресурс не был локально объявлен. В настоящее время код будет выполняться, и не будет выдаваться никаких компиляционных ошибок.