【问题标题】:Why is close() method of the resource called before catch in a try-with-resources construct in Java?为什么在 Java 中的 try-with-resources 构造中调用资源的 close() 方法?
【发布时间】:2014-09-23 07:09:29
【问题描述】:

我碰巧意识到,情况就是这样。请参阅下面的示例:

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 部分,并避免资源泄漏。为什么在 catch 部分之前关闭资源?其背后的原因/想法/局限是什么?

【问题讨论】:

    标签: java try-with-resources autocloseable


    【解决方案1】:

    答案可以在JLS §14.20.3.2找到;关键部分是最后两段,尤其是倒数第二段的最后一句(我已经强调过了):

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

    扩展try-with-resources语句的含义:

    try ResourceSpecification
        Block
    [Catches]
    [Finally]
    

    由以下对嵌套在try-catchtry-finallytry-catch-finally 语句中的基本try-with-resources 语句的翻译给出:

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

    翻译的效果是将资源规范“放入”try 语句中。 这允许扩展try-with-resources 语句的catch 子句捕获由于任何资源的自动初始化或关闭而引起的异常。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 2013-09-12
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      相关资源
      最近更新 更多