Java - попробуйте с ресурсами

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 .