在 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
初始化成功,所以会关闭
假设我在 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
初始化成功,所以会关闭