Mastery
Mastery/Java/F. Exceptions
T1 · high-leverage
Compare with Python: Guaranteed cleanup, even when the body throws

try-with-resources, AutoCloseable, and suppressed exceptions

Resources declared in the try(...) parens get close() called automatically, in reverse declaration order, even if the body throws. If close() itself throws while an exception from the body is already propagating, the close-time exception isn't lost -- it's attached to the primary one as a suppressed exception, retrievable via getSuppressed(), rather than silently replacing the original.

java
class NoisyResource implements AutoCloseable {
    String name;
    NoisyResource(String name) { this.name = name; System.out.println("  open " + name); }
    public void close() { System.out.println("  close " + name); }
}

try (var a = new NoisyResource("A"); var b = new NoisyResource("B")) {
    System.out.println("  using both");
}
// note the close order below: B, then A -- reverse of declaration order
java
class FailingResource implements AutoCloseable {
    public void close() throws Exception {
        System.out.println("  close FailingResource (throws)");
        throw new IllegalStateException("close failed");
    }
}

try {
    try (var f = new FailingResource()) {
        throw new RuntimeException("primary failure in body");
    }
} catch (RuntimeException e) {
    System.out.println("primary exception: " + e.getMessage());
    for (Throwable suppressed : e.getSuppressed()) {
        System.out.println("suppressed: " + suppressed.getClass().getSimpleName() + ": " + suppressed.getMessage());
    }
}

Interview angle

"What happens if both the try block AND close() throw?" is a great follow-up once a candidate demonstrates they know try-with-resources exists — the correct answer (the body's exception propagates as primary, the close-time one is attached via getSuppressed(), neither is silently lost) shows they understand the mechanism, not just the syntax sugar.

In the industry

Try-with-resources is the default, expected idiom for anything implementing AutoCloseable in modern Java — manual finally { resource.close(); } blocks are a routine code-review comment asking "why not try-with-resources?" unless there's a specific reason (e.g. needing the resource to outlive the block). The suppressed-exception mechanism specifically exists because early Java's manual cleanup code had a well-known failure mode: a close() exception in a finally block would silently replace the original exception, destroying the actual root cause.