try-with-resources
AutoCloseable vs Closeable, what javac desugars try-with-resources into, reverse close order, suppressed exceptions with addSuppressed and getSuppressed, Java 9 effectively final resources, and the resource leaks that exhaust connection pools in production.
On this page
🧹 What is try-with-resources?
try-with-resources is a try statement that declares one or more resources in parentheses and guarantees each one is closed when the block exits, normally or by exception. try (Connection conn = dataSource.getConnection()) { ... } returns the connection to the pool even if the query inside throws. Any object whose class implements AutoCloseable can be a resource. It arrived in Java 7 and replaced the error-prone try/finally pattern for cleanup.
For this lesson, we'll focus on what javac turns a try-with-resources statement into, the order resources are closed in, how a failing close() is recorded as a suppressed exception instead of hiding the real error, the Java 9 syntax for existing variables, and the production incidents that happen when resources leak. Interviewers like this topic because it has a clean "what does this print?" angle (close order and suppressed exceptions) and a very real production angle: a single missing close() can take down a service by exhausting its connection pool.
Below the line (out of scope)
- How
finallyis compiled and when it doesn't run: How exceptions work in Java Cleanerand why finalizers were deprecated: The final keyword in Java- Connection pool sizing and tuning: Databases module
The 30-second answer
try-with-resources closes every declared resource automatically when the block exits, in reverse order of declaration, and before any catch or finally attached to it runs. A resource must implement AutoCloseable, whose close() throws Exception; Closeable is the older I/O subinterface that throws IOException and must be idempotent. javac desugars it into nested try/catch/finally code that calls close() and, if the body already threw, attaches any exception from close() to the original with addSuppressed(), so the real error is never masked. Since Java 9 you can write try (conn) for an existing final or effectively final variable. In production, forgetting it on JDBC connections, HTTP responses or Files.lines() leaks pooled connections or file handles until the service stalls.
What you’ll learn
- Tell
AutoCloseablefromCloseable(exception type, idempotency) and write a correctclose() - Describe the desugared form of try-with-resources from JLS §14.20.3
- Predict the close order and know that resources are closed before your
catchandfinallyrun - Explain suppressed exceptions (
addSuppressed,getSuppressed) and why plaintry/finallymasks errors - Use the Java 9
try (existingVar)form and avoid the wrapped-constructor leak - Recognise connection pool exhaustion and file-handle leaks in production, and detect them with leak detection
Interview radar
Asked very often: Why is try-with-resources better than try/finally, and in what order are resources closed?
Senior rounds probe: What is a suppressed exception, what does the desugared code look like, and is the resource still open inside the catch block?
Production angle: HikariCP's "Connection is not available, request timed out after 30000ms" caused by a code path that never closes its connection.
01Picture it first: a stack of borrowed library books
Think of each resource as a book you borrowed from a library that only has a few copies. You borrow the connection, then the statement, then the result set, stacking them up. When you're done, you return them from the top of the pile down: result set first, connection last, because the result set depends on the statement, which depends on the connection. And if you trip on the way to the desk (an exception), the librarian still collects every book, and makes a note of any that were damaged without forgetting why you tripped.
The diagram below shows that order for three JDBC resources and where your catch and finally blocks fit in.
Close order in try-with-resources: Connection, PreparedStatement and ResultSet are opened in steps 1 to 3, the body runs, then they are closed in reverse order, ResultSet, PreparedStatement, Connection, and only after all three are closed does the catch block run, followed by finally
02Under the hood: AutoCloseable, Closeable and what javac generates
Premium lesson
Keep reading with the Java Pass
The rest of this lesson is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.
- Suppressed exceptions: why try/finally was broken
- Real world: leaks that took services down
- Advanced: the edge cases interviewers probe
- How to say it in the interview
From ₹199 · one-time payment · No auto-renewal
Further reading (10)
- JLS §14.20.3: try-with-resources
- AutoCloseable (Java SE 21 Javadoc)
- Closeable (Java SE 21 Javadoc)
- Throwable.addSuppressed (Java SE 21 Javadoc)
- Oracle Java Tutorials: The try-with-resources Statement
- JEP 213: Milling Project Coin (effectively final resources)
- JEP 456: Unnamed Variables & Patterns
- HikariCP: configuration (connectionTimeout, leakDetectionThreshold)
- Effective Java, 3rd ed., Item 9: Prefer try-with-resources to try-finally
- Baeldung: Java try-with-resources