1. Обзор
Поддержка try-with-resources,
представленная в Java 7, позволяет нам объявлять ресурсы, которые будут использоваться в блоке try
, с гарантией того, что ресурсы будут закрыты после выполнения этого блока.
Объявленные ресурсы должны реализовать интерфейс AutoCloseable
.
2. Использование попытки с ресурсами
Проще говоря, для автоматического закрытия ресурс должен быть объявлен и инициализирован внутри 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
:
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();
}
Здесь можно продолжить изучение класса Scanner
.
4. попробуйте с ресурсами
с несколькими ресурсами
Мы можем просто объявить несколько ресурсов в блоке 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();
}
}
Выход:
Конструктор -> AutoCloseableResources_First
Конструктор -> AutoCloseableResources_Second
Something -> AutoCloseableResources_First
Something -> AutoCloseableResources_Second
Closed AutoCloseableResources_Second
Closed AutoCloseableResources_First
7. поймать
и наконец
Блок try-with-resources
может по-прежнему иметь блоки catch
`` и finally ,
которые будут работать так же, как и в традиционном блоке try .
8. Java 9 — эффективные окончательные `` переменные
До Java 9 мы могли использовать свежие переменные только внутри блока try-with-resources :
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
// omitted
}
Как показано выше, это было особенно многословно при объявлении нескольких ресурсов. Начиная с Java 9 и как часть JEP 213 , теперь мы можем использовать переменные final
или даже эффективно final внутри блока try-with-resources
:
final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) {
// omitted
}
Проще говоря, переменная фактически является final , если она не изменяется после первого присваивания, даже если она явно не помечена как final
.
Как показано выше, переменная сканера явно объявлена как
final
, поэтому мы можем использовать ее с блоком try-with-resources .
Хотя переменная записи
не является явно окончательной,
она не меняется после первого присваивания. Таким образом, мы также можем использовать переменную записи .
9. Заключение
В этой статье мы обсудили, как использовать try-with-resources и как заменить try
, catch
и, наконец
, try-with-resources.
Мы также рассмотрели создание пользовательских ресурсов с помощью AutoCloseable
и порядок, в котором ресурсы закрываются.
Полный исходный код примера доступен в этом проекте GitHub .