Since Java 9 we can use effectively final variables in try-with-resources.
The example below presents a situation where one of the resources initialization throws an exception.
public static void main(String[] args) {
Resource1 r1 = new Resource1();
Resource2 r2 = new Resource2(); // exception will be thrown
try (r1; r2) {
System.out.println("TryWithResources.main() try");
} catch (Exception e) {
System.out.println("TryWithResources.main() catch");
}
}
static class Resource1 implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("TryWithResources.Resource1.close()");
}
}
static class Resource2 implements AutoCloseable {
public Resource2() {
throw new RuntimeException();
}
@Override
public void close() throws Exception {
System.out.println("TryWithResources.Resource2.close()");
}
}
When I run this example, the only output I get is a RuntimeException, meaning that Resource1 was not closed. That was expected, since it wasn't initialized in the try-with-resources.
But, is this the expected outcome, or am I missing anything?
Because, if this is actually the way it is supposed to work, then It seems to me that this new syntax actually removes a lot of the safety that was brought originally by the try-with-resources statement.
Can someone please confirm if that really is the case? And, if positive, why would we ever use this syntax with multiple resources and take that risk?