Try-With-Resources in Java
Files, database connections and network sockets are resources: borrowed from the operating system, and they must be given back by calling close(). Forget, and the program slowly runs out of file handles or connections. Writing close() in a finally block works but is long and easy to get wrong. Try-with-resources (Java 7) lets you open resources in the try header, and Java closes them automatically at the end, however the block ends.
Opening and Closing Automatically
public class Resources {
static class Connection implements AutoCloseable {
private final String name;
Connection(String name) {
this.name = name;
System.out.println("open " + name);
}
void send(String message) {
if (message.isBlank()) {
throw new IllegalArgumentException("empty message");
}
System.out.println(name + " sent: " + message);
}
@Override
public void close() {
System.out.println("close " + name);
}
}
public static void main(String[] args) {
try (Connection db = new Connection("database");
Connection sms = new Connection("sms-gateway")) {
db.send("order saved for Navika");
sms.send(" ");
} catch (IllegalArgumentException e) {
System.out.println("caught: " + e.getMessage());
}
}
}open database
open sms-gateway
database sent: order saved for Navika
close sms-gateway
close database
caught: empty messageHow it works
- Resources are declared in parentheses after
try, separated by semicolons. Each must implementAutoCloseable. - The body throws an exception on the second
send. - Before the
catchruns, Java closes both resources, in reverse order of opening: the last one opened is closed first, so a resource is never closed while something opened after it still depends on it. - Only then does the
catchrun.
Why It Beats finally
The same job with finally needs a null check, a nested try for close(), and still loses information when closing fails:
Connection db = null;
try {
db = new Connection("database");
db.send("order saved");
} finally {
if (db != null) {
db.close(); // if this throws, the original exception is lost
}
}finally | try-with-resources | |
|---|---|---|
| Lines of code | Many, with null checks | One header |
| Forgetting to close | Possible | Impossible |
| Several resources | Nested try blocks | Listed in one header, closed in reverse order |
| Exception while closing | Replaces the original exception | Kept as a suppressed exception; the original survives (see "Suppressed Exceptions in Java") |
Real Resources
Most JDK classes that hold something open implement AutoCloseable, so they work in the header directly: FileReader, BufferedReader, Scanner reading a file, InputStream and OutputStream, JDBC Connection, Statement and ResultSet, and ExecutorService (since Java 19). File and database lessons later in the course use try-with-resources everywhere.
Common Mistakes
Creating the resource before the try and forgetting to put it in the header. Then it isn't closed automatically.
Wrapping a Scanner on System.in in try-with-resources. Closing it closes System.in for the rest of the program.
Expecting resources to still be usable in the catch or finally. They're already closed, and they're out of scope.
Interview Corner
What is try-with-resources?
It's a form of the try statement, introduced in Java 7, that declares one or more resources in parentheses after try. Each resource must implement AutoCloseable, and Java automatically calls close() on all of them when the block finishes, normally or because of an exception, in the reverse order of declaration. Exceptions thrown while closing are added as suppressed exceptions to the main one.
In what order are resources closed?
In the reverse order of their declaration: the last resource opened is the first one closed. This ensures resources that depend on earlier ones are released first.
Practice
- Easy: Give the
Connectionclass a third instance,"email", in the header, and predict the order of the "open" and "close" lines. - Harder: Write a
Timerclass that implementsAutoCloseable, records the time in its constructor and prints the elapsed milliseconds inclose(). Use it to time a loop.
Key Takeaways
Was this tutorial helpful?