The second resource's constructor throws. What does this program print?
```java
public class Main {
static class R implements AutoCloseable {
final String n;
R(String n) {
this.n = n;
System.out.print("open" + n + " ");
if (n.equals("B")) {
throw new RuntimeException("ctorB");
}
}
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"); R c = new R("C")) {
System.out.print("body ");
} catch (RuntimeException e) {
System.out.print("caught " + e.getMessage() + " sup=" + e.getSuppressed().length);
}
}
}
```
A. openA openB closeA caught ctorB sup=0Correct answer
Correct: A opens fully, then B's constructor prints openB and throws, so b is never assigned and is not closed; only the completed resource A is closed, and ctorB is caught with nothing suppressed.
B. openA openB closeB closeA caught ctorB sup=0
Assumes B counts as open because its constructor started running; a resource variable is initialized only if its initializer completes normally, so B is never closed.
C. openA openB openC body closeC closeB closeA
Assumes initialization continues past the throwing constructor and the body still runs; a throwing initializer stops the statement, skipping C and the body entirely.
D. openA openB caught ctorB sup=0
Assumes a failing initializer aborts the whole statement without closing anything; that would leak A, which is precisely what try-with-resources exists to prevent, so A is still closed.
Explanation
Trace: resources are initialized left to right. `new R("A")` prints `openA ` and completes, so a is a live resource. `new R("B")` prints `openB ` and then throws ctorB from inside the constructor — b is never assigned, and a resource whose initializer did not complete normally is never closed. Initialization stops there, so `new R("C")` never runs and the body never runs. The resources that were successfully opened are closed in reverse declaration order, which here is just a: `closeA `. The ctorB exception then reaches the catch clause. Nothing was suppressed, because close() on a completed normally — suppression needs a close() that throws. Output: `openA openB closeA caught ctorB sup=0`.
Why the others are wrong:
`openA openB closeB closeA caught ctorB sup=0` assumes B counts as open because its constructor started running; the resource variable is only considered initialized if its initializer completes normally.
`openA openB caught ctorB sup=0` assumes a failing initializer aborts the whole statement without closing anything — that would leak A, which is precisely what try-with-resources exists to prevent.
`openA openB openC body closeC closeB closeA` assumes initialization continues past a throwing constructor and the body still runs.
Exam tip: a try-with-resources statement has three independent failure sites — initializer, body, close. An initializer that throws closes exactly the resources declared before it, in reverse order, and skips the body and every later initializer. getSuppressed() stays empty unless a close() itself throws while another exception is already in flight.