try-with-resources in Java
AutoCloseable resources closed automatically in reverse order.
close() line below never runs. Do that 10,000 times on a server and the OS refuses to open any more files.Auto-close
Declare a resource in parentheses after try and it is closed automatically when the block ends — normally or because of an exception. The resource type must implement **AutoCloseable** (Closeable extends it). Since Java 9, an effectively final variable can be listed directly: try (in) { ... }.
try (var in = Files.newBufferedReader(path)) {
return in.readLine();
} // in.close() is called automaticallyTwo resources
What does this print?
record R(String n) implements AutoCloseable {
public void close() { System.out.print(n); }
}
void main() {
try (var a = new R("A"); var b = new R("B")) {
System.out.print("body ");
}
}body BAbody ABBA body
Show the answer
Resources close after the body, in reverse order of declaration: last opened, first closed. Later resources often depend on earlier ones, so they must go first.
The order of events
When the body throws: 1. resources are closed (in reverse order), 2. the matching catch runs, 3. finally runs. So close() happens before your catch and finally blocks ever see the exception.
Close, catch, finally
A try-with-resources body throws IllegalStateException. There's a catch for it that prints X, a finally that prints F, and close() prints C. What's printed?
Think about it, then reveal the answer
CXF — the resource is closed as soon as the body exits, then the catch runs, and finally comes last.
Not every object is a resource
Only AutoCloseable types can be declared in the parentheses. A plain class is a compile error — Java must know there's a close() to call.
class Plain { }
try (var p = new Plain()) { // error
System.out.println("ok");
}Reading a file
var in = new FileInputStream(f);
byte[] data = in.readAllBytes();
in.close();If readAllBytes() throws, close() never runs.
try (var in = new FileInputStream(f)) {
byte[] data = in.readAllBytes();
}Closed on every path, including exceptions.
Databases and pools
JDBC code opens a Connection, then a PreparedStatement, then a ResultSet — all in one try-with-resources, closed in reverse order. Leaking connections is a classic production outage: the pool runs dry and every request waits forever.
Key takeaways
- The resource type must implement AutoCloseable (Closeable extends it)
- Closed in reverse order: last opened, first closed
- close() runs before the catch and finally blocks
- Java 9+: an effectively final variable can be listed: try (in) { ... }
AutoCloseable was created in Java 7 as a new parent of the older Closeable (Java 5), so every existing stream worked with try-with-resources from day one.
Practice questions
What does this print?
record Res(String n) implements AutoCloseable {
public void close() { System.out.println("close " + n); }
}
void main() {
try (var a = new Res("A"); var b = new Res("B")) {
System.out.println("body");
}
}- body close B close A
- body close A close B
- close A close B body
- body
Check your answer
body close B close A. Resources are closed after the body, in reverse order of declaration: B first, then A.
What does this print?
record Res() implements AutoCloseable {
public void close() { System.out.print("C"); }
}
void main() {
try (var r = new Res()) {
throw new IllegalStateException();
} catch (IllegalStateException e) {
System.out.print("X");
} finally { System.out.print("F"); }
}- CXF
- XCF
- XFC
- CFX
Check your answer
CXF. The resource is closed as soon as the try body exits, before the catch runs; finally comes last.