在 try-with-resources 声明期间抛出异常

Exception thrown during try-with-resources declaration

假设我在 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...");
    }

}

输出:

Closing Resource1...

Exception in thread "main" java.lang.RuntimeException: Bad resource!

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

是的,这是有保证的。引用自 JLS section 14.20.3:

Resources are initialized in left-to-right order. If a resource fails to initialize (that is, its initializer expression throws an exception), then all resources initialized so far by the try-with-resources statement are closed. If all resources initialize successfully, the try block executes as normal and then all non-null resources of the try-with-resources statement are closed.

这种情况下,如果第二个new MyResource()抛出异常,由于myResource1初始化成功,所以会关闭