1. Обзор
Поддержка try-with-resources - введена в Java 7 - позволяет нам объявлять ресурсы, которые будут использоваться в блоке try , с гарантией того, что ресурсы будут закрыты после выполнения этого блока. Объявленные ресурсы должны реализовывать интерфейс AutoCloseable .
2. Использование try-with-resources
Проще говоря, для автоматического закрытия ресурс должен быть объявлен и инициализирован внутри try , как показано ниже:
try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
writer.println("Hello World");
}
3. Замена try – catch-finally на try-with-resources
Простой и очевидный способ использования новой функциональности try-with-resources состоит в замене традиционного и многословного блока try-catch-finally .
Давайте сравним следующие примеры кода - сначала это типичный блок try-catch-finally , затем новый подход с использованием эквивалентного блока try-with-resources:
Scanner scanner = null;
try {
scanner = new Scanner(new File("test.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
А вот супер сжатое решение с использованием try-with-resources:
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
4. try-with-resources с несколькими ресурсами
Несколько блоков могут быть точно объявлены в блоке try-with-resources , разделяя их точкой с запятой:
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
while (scanner.hasNext()) {
writer.print(scanner.nextLine());
}
}
5. Пользовательский ресурс с __ AutoCloseable
__
Чтобы создать собственный ресурс, который будет правильно обрабатываться блоком try-with-resources , класс должен реализовать интерфейсы Closeable или AutoCloseable и переопределить метод close :
public class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Closed MyResource");
}
}
6. Порядок закрытия ресурсов
Ресурсы, которые были определены/приобретены первыми, будут закрыты последними; Давайте посмотрим на пример такого поведения:
Ресурс 1:
public class AutoCloseableResourcesFirst implements AutoCloseable {
public AutoCloseableResourcesFirst() {
System.out.println("Constructor -> AutoCloseableResources__First");
}
public void doSomething() {
System.out.println("Something -> AutoCloseableResources__First");
}
@Override
public void close() throws Exception {
System.out.println("Closed AutoCloseableResources__First");
}
}
Ресурс 2:
public class AutoCloseableResourcesSecond implements AutoCloseable {
public AutoCloseableResourcesSecond() {
System.out.println("Constructor -> AutoCloseableResources__Second");
}
public void doSomething() {
System.out.println("Something -> AutoCloseableResources__Second");
}
@Override
public void close() throws Exception {
System.out.println("Closed AutoCloseableResources__Second");
}
}
Код:
private void orderOfClosingResources() throws Exception {
try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst();
AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) {
af.doSomething();
as.doSomething();
}
}
Вывод:
Constructor → AutoCloseableResources First Constructor → AutoCloseableResources Second Something → AutoCloseableResources First Something → AutoCloseableResources Second Closed AutoCloseableResources Second Closed AutoCloseableResources__First
7. catch & finally
Блок try-with-resources все еще может иметь блоки catch и finally , которые будут работать так же, как и с традиционным блоком try .
8. Заключение
В этой статье мы обсудили, как использовать try-with-resources, как заменить try , catch и finally на try-with-resources, создать пользовательские ресурсы с AutoCloseable и порядок, в котором ресурсы закрыты.
Полный исходный код для примера доступен в this проекте GitHub .