为什么在Java中的try-with-resources构造中catch之前调用资源的close()方法?

时间:2014-07-31 10:59:42

标签: java try-with-resources autocloseable

我碰巧意识到,情况确实如此。请参阅以下示例:

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旨在避免使用null检查的杂乱的finally段并避免泄漏的资源。为什么资源在捕获部分之前关闭?它背后的原因/想法/限制是什么?

1 个答案:

答案 0 :(得分:8)

答案可以在JLS §14.20.3.2中找到;关键部分是最后两段,特别是倒数第二段的最后一句(我强调它):

  

具有至少一个try-with-resources子句和/或catch子句的finally语句称为扩展 try-with-resources语句。

     

扩展try-with-resources声明的含义:

try ResourceSpecification
    Block
[Catches]
[Finally]
     

通过以下翻译给出嵌套在try-with-resourcestry-catchtry-finally声明中的基本try-catch-finally声明:

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

翻译的效果是将资源规范放在内部" try声明。 这允许扩展catch语句的try-with-resources子句由于自动初始化或关闭任何资源而捕获异常。

     

此外,所有资源都会在finally块执行时关闭(或尝试关闭),与finally关键字的意图保持一致。