Java 在try with resources声明期间引发异常

Java 在try with resources声明期间引发异常,java,try-with-resources,Java,Try With Resources,假设我有以下Java中的try with resources语句: try (MyResource myResource1 = new MyResource(); MyResource myResource2 = new MyResource()) { // do stuff... } 如果MyResource myResource2=new MyResource()引发异常,是否保证调用myResource1.close() public static void main(Strin

假设我有以下Java中的try with resources语句:

try (MyResource myResource1 = new MyResource(); MyResource myResource2 = new MyResource()) {
    // do stuff...
}
如果
MyResource myResource2=new MyResource()
引发异常,是否保证调用
myResource1.close()

public static void main(String[] args) {
    try (Resource1 myResource1 = new Resource1(); Resource2 myResource2 = new Resource2()) {
        // do stuff...
    }
}


class Resource1 implements AutoCloseable {

    @Override
    public void close() {
        System.out.println("Closing Resource1...");
    }

}

class Resource2 implements AutoCloseable {

    public Resource2() {
        throw new RuntimeException("Bad resource!");
    }

    @Override
    public void close() {
        System.out.println("Closing Resource2...");
    }

}
输出:

正在关闭资源1

线程“main”java.lang.RuntimeException中出现异常:资源错误


这表明第一个资源已关闭。

是的,这是有保证的。引述自:

资源按从左到右的顺序初始化如果资源未能初始化(即,其初始值设定项表达式引发异常),则到目前为止由try with resources语句初始化的所有资源都将关闭。如果所有资源初始化成功,try块将正常执行,然后try with resources语句的所有非空资源都将关闭


在这种情况下,如果第二个
new MyResource()
抛出异常,因为
myResource1
已成功初始化,它将被关闭。

是,只要资源实现java.lang.AutoCloseableyes,它与finally相同,但资源必须实现java.lang.AutoCloseableyesAutoClosable@Tunaki-它用java 8I编译,我编辑它来构造对象。关键是try声明期间抛出的异常(括号之间)是否会被捕获,或者是否只会捕获大括号之间的异常。这并不能回答“它有保证吗?”。这回答了对于您的特定JDK,对于这个特定的执行,它是有效的。@Tunaki它确实回答了这个问题。我只是选择通过一个简单的例子来展示它,而不是引用规范。这个例子并不保证它是真的,这就是我要说的。您需要在所有可能的JDK实现的所有版本上测试您的示例。