The constructor of the SECOND resource throws. What does this program print?
```java
public class Main {
static class R implements AutoCloseable {
private final String n;
R(String n) {
this.n = n;
System.out.print("open" + n + " ");
if (n.equals("B")) {
throw new IllegalStateException("boom");
}
}
@Override
public void close() {
System.out.print("close" + n + " ");
}
}
public static void main(String[] args) {
try (R a = new R("A"); R b = new R("B")) {
System.out.print("body ");
} catch (Exception e) {
System.out.print("caught");
}
}
}
```
A. openA openB body closeA caught
Wrong: this assumes the body runs anyway. That is the behaviour of a resource that evaluates to null (body runs, close skipped), not of a resource initializer that throws - here the body is skipped entirely.
B. openA openB caught
Wrong: this assumes a failure in the header closes nothing, which would leak the resource already opened - precisely what try-with-resources exists to prevent. The initialized first resource is still closed.
C. openA openB closeB closeA caught
Wrong: this assumes a resource whose constructor threw still gets closed. The second resource variable was never assigned, so close() cannot be invoked on it; only resources whose initializer completed normally are closed.
D. openA openB closeA caughtCorrect answer
Correct: the second constructor prints openB then throws before b is assigned, so the body is skipped and only the successfully initialized first resource is closed (closeA), then the exception is caught.
Explanation
Trace: resource initializers run left to right. `new R("A")` succeeds and prints `openA `, so a is an initialized resource. `new R("B")` prints `openB ` and then throws, so b is NEVER successfully initialized. The try BODY does not run at all — it is only entered once every resource in the header is initialized. Java then closes the resources that were successfully initialized, in reverse order: only a qualifies, so `closeA ` prints. b's close() is not called: there is no object to close it on. The IllegalStateException propagates out of the header and is caught, printing `caught`.
Why the others are wrong:
`openA openB closeB closeA caught` assumes a resource whose constructor threw still gets closed. The resource variable was never assigned, so close() cannot be invoked on it — close() is only called for resources whose initializer completed normally.
`openA openB caught` assumes a failure anywhere in the header abandons the whole statement without closing anything, which would leak the resource that was already open — precisely what try-with-resources exists to prevent.
`openA openB body closeA caught` assumes the body runs anyway. That is the behaviour of a resource that evaluates to null (body runs, close skipped), not of a resource initializer that throws.
Exam tip: split try-with-resources into header, body, close. If the header throws part-way, the body is skipped entirely and exactly the resources already initialized are closed, in reverse order. The reverse trap: `try (R r = null)` — the initializer completed normally, so the body DOES run, and close() is simply skipped on the null reference.