Почему метод close() ресурса вызывается перед catch в конструкции try-with-resources в Java?

Я случайно понял, что это так. Смотрите этот пример ниже:

public class AutoClosableTest {
    public static void main(String[] args) throws Exception {
        try (MyClosable instance = new MyClosable()) {
            if (true) {
                System.out.println( "try" );
                throw new Exception("Foo");
            }
        } catch( Exception e ) {
            System.out.println( "Catched" );
        } finally {
            System.out.println( "Finally" );
        }
    }

    public static class MyClosable implements AutoCloseable {
        @Override
        public void close() throws Exception {
            System.out.println( "Closed." );
        }
    }
}

Это печатает:

пытаться
Закрыто.
перехваченных
в заключение

Вопрос

Метод try-with-resources предназначен для того, чтобы избежать беспорядочных разделов finally с нулевыми проверками и избежать утечек ресурсов. Почему ресурсы закрываются ДО секции catch? В чем причина / идея / ограничение?

1 ответ

Решение

Ответ может быть найден в JLS § 14.20.3.2; ключевые части - это последние два абзаца, особенно последнее предложение предпоследнего абзаца (я подчеркнул это):

try-with-resources заявление по крайней мере с одним catch пункт и / или finally пункт называется расширенным try-with-resources заявление.

Значение расширенного try-with-resources заявление:

try ResourceSpecification
    Block
[Catches]
[Finally]

дается следующий перевод в основной try-with-resources заявление, вложенное в try-catch или же try-finally или же try-catch-finally заявление:

try {
    try ResourceSpecification
        Block
}
[Catches]
[Finally]

Эффект перевода состоит в том, чтобы поместить спецификацию ресурса "внутрь" try заявление. Это позволяет catch пункт расширенного try-with-resources оператор для перехвата исключения из-за автоматической инициализации или закрытия любого ресурса.

Кроме того, все ресурсы будут закрыты (или будут пытаться закрыться) к тому времени, когда finally блок выполняется в соответствии с намерением finally ключевое слово.

Другие вопросы по тегам