Why is try-with-resources usually preferred over a manual try-finally for closing resources?
answer
- Manual finally: boilerplate + null check + close can throw
- close() in finally can mask the body's real exception
- try-with-resources auto-closes AutoCloseable, reverse order
- Body exception is primary; close exception is suppressed
- Effective Java Item 9: prefer try-with-resources
basics
~10 stry-with-resources auto-closes resources for you and keeps the real error visible. Manual finally is verbose and, if close() also throws, it can hide the original exception. try-with-resources avoids that.
solid answer
~50 sWith a manual try-finally you must remember to call close() yourself, guard against the resource being null, and handle the case where close() itself throws. The dangerous part: if the try body throws and then close() in finally also throws, the close exception replaces the original one, hiding the real failure. try-with-resources, added in Java 7, fixes all of this: any resource declared in the try (...) header that implements AutoCloseable is closed automatically in reverse order of acquisition, and if both the body and close() throw, the body's exception is kept as the primary while close()'s is attached as a suppressed exception you can retrieve via getSuppressed(). It is shorter, harder to get wrong, and preserves exception fidelity. Manual finally is still appropriate for non-resource cleanup such as restoring a flag or releasing a lock that is not AutoCloseable.
go deeper
Knows try-with-resources closes resources automatically so you do not write close() by hand.
Explains the boilerplate and null-check savings and that it handles multiple resources cleanly.
Articulates the exception-masking problem with manual finally and how suppressed exceptions preserve the primary failure.
Sets standards for resource handling and exception fidelity, knows when manual finally is still warranted, and reasons about diagnostics/observability of failures.
## The manual try-finally idiom (pre-Java 7) Before Java 7, closing a resource meant: ```java InputStream in = null; try { in = new FileInputStream(path); // use in } finally { if (in != null) { in.close(); // can itself throw! } } ``` Three recurring problems: 1. **Boilerplate**: null-check and explicit close every time. 2. **Multiple resources nest**: two resources require nested try-finally, which is easy to mis-order. 3. **Exception masking**: if the body throws exception A and then `in.close()` throws exception B inside finally, B replaces A (because, per the JLS, finally completing abruptly overrides the try). The *real* failure A is lost - you only see the close failure. ## try-with-resources (Java 7+) Declare resources in the `try` header; they are auto-closed: ```java try (InputStream in = new FileInputStream(path); OutputStream out = new FileOutputStream(dest)) { // use in and out } // both closed automatically, out first then in (reverse order) ``` Key terms: - **AutoCloseable**: an interface with a single `close()` method; any type implementing it can be managed by try-with-resources. (`Closeable` extends it for I/O.) - **Suppressed exception**: a secondary throwable attached to a primary one, retrievable via `Throwable.getSuppressed()`. ## How it fixes exception masking If the body throws A and a `close()` throws B, try-with-resources keeps **A as primary** and records **B as suppressed** on A (`a.getSuppressed()` returns [B]). Nothing is lost; the stack trace shows A with a 'Suppressed:' section for B. The manual finally idiom does the opposite by default - it loses A. ## Other advantages - **Reverse-order, guaranteed close** of multiple resources, even if an earlier one's close throws. - **Less code**, fewer null checks, no forgetting to close. - **Scope clarity**: the resource is visibly tied to the block. ## When manual finally is still right try-with-resources only manages `AutoCloseable` resources. Use a manual finally for cleanup that is not an AutoCloseable: restoring a thread-local or a boolean flag, calling a non-AutoCloseable unlock (or use lock with a finally as the standard ReentrantLock idiom), or other state restoration. So the two coexist: try-with-resources for closing, finally for arbitrary cleanup. ## Effective Java guidance The canonical advice (Effective Java, Item 9) is: "prefer try-with-resources to try-finally." It is shorter, cleaner, and produces better diagnostics in every case where you would otherwise close a resource by hand.
- In what order are resources closed in a multi-resource try-with-resources?Reverse order of declaration: the last-acquired resource is closed first, mirroring nested try-finally.
- Where does the secondary exception go if both the body and close() throw?The body's exception is primary; the close() exception is attached as a suppressed exception, retrievable via getSuppressed().
saying these in an interview costs you the question
- Claiming finally is always better/clearer than try-with-resources
- Not knowing close() failing in finally hides the original exception
- Thinking try-with-resources can manage any object (only AutoCloseable)
- Believing try-with-resources removes the need for finally entirely