СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

H Когда try-with-resources не срабатывает в черновиках

Хотел бы поделиться с читателями недавно замеченной особоенностью работы конструкции try-with-resources.

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


Например, в следующем коде bar создается внутри блока try, но не в самом блоке, а в конструкторе объекта. Как показывает результат работы кода ниже, тело этого конструктора выполняется вне контекста try(...)!

public class CloseTest implements AutoCloseable{

    public static void main(String[] args) {
        try(CloseTest ct = new CloseTest()){
            ct.doSome();
        }
    }
    private CloseTest() {
        Bar bar = new Bar();
        //используем bar, что-то делем, и вдруг у нас возникает исключение
        throw new RuntimeException("test");
    }
    private void doSome() {System.out.println("doSome"); }
    
    @Override
    public void close() {
        System.out.println("CloseTest autoclose!");
    }
}

class Bar implements AutoCloseable{
    @Override
    public void close() {
        System.out.println("autoclose bar");
    }
}



«autoclose bar» не выводится.

Таким образом, несмотря на то, что у нас Bar имплементит AutoCloseable, а код исполняется внутри try(), он ресурсом уже как бы не является, поэтому автоматически освобожден не будет.

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

комментарии (0)