Порядок выполнения методов Closeable и AutoCloseable close () - PullRequest
1 голос
/ 17 апреля 2019

Может кто-нибудь объяснить мне, что здесь происходит и в каком порядке? Вывод не имеет никакого смысла для меня.

Выход T 1 IOE F.

Код:

import java.io.Closeable;
import java.io.IOException;

public class TestRes {
    public static void main(String[] args) {
    try (
            MyResource11 r1 = new MyResource11();
            MyResource21 r2 = new MyResource21();
            ) 
        {
            System.out.print("T ");
        } catch (IOException ioe) {
            System.out.print("IOE ");
        } finally {
            System.out.print("F ");
        }
    }
}

class MyResource11 implements AutoCloseable {
    public void close() throws IOException {
        System.out.print("1 ");
    }
}

class MyResource21 implements Closeable {
    public void close() throws IOException {
        throw new IOException();
    }
}

Ответы [ 2 ]

4 голосов
/ 17 апреля 2019

try-with-resources закрывает ресурсы в порядке напротив в том порядке, в котором они были объявлены. Код:

  1. Печатает T
  2. Оператор try-with-resources пытается закрыть r2
  3. При этом возникает исключение
  4. Оператор try-with-resources успешно закрывает r1, что приводит к выводу 1
  5. Блок исключений запускается (за исключением r2) и выводит IOE
  6. Блок finally выполняется, выводя F

Этостоит прочесть в разделе try-with-resources части JLS , которая включает в себя примеры кода развернутого оператора try-with-resources (например, эквивалентный код с try / catch / finally).Из этого раздела:

Ресурсы закрываются в порядке, обратном тому, в котором они были инициализированы.Ресурс закрывается, только если он инициализирован ненулевым значениемИсключение из закрытия одного ресурса не препятствует закрытию других ресурсов.Такое исключение подавляется, если исключение было сгенерировано ранее инициализатором, блоком try или закрытием ресурса.

2 голосов
/ 17 апреля 2019

Ваш код является ярлыком для

public static void main(String[] args) {
    try {
        MyResource11 r1 = new MyResource11();
        try {
            MyResource21 r2 = new MyResource21();
            try {
                System.out.print("T ");
            } finally {
                r2.close();
            }
        } finally {
            r1.close();
        }
    } catch (IOException ioe) {
        System.out.print("IOE ");
    } finally {
        System.out.print("F ");
    }
}
...