How to close resources automatically
Short answer
Declare the resource in parentheses after try. Java calls its close() when leaving the block — even if an exception happened:
void main() throws IOException {
Files.writeString(Path.of("data.txt"), "line 1\nline 2\n");
try (BufferedReader reader = Files.newBufferedReader(Path.of("data.txt"))) {
IO.println(reader.readLine());
}
}Output:
line 1Several resources
List the resources separated by semicolons. They are closed in reverse order:
void main() throws IOException {
Files.writeString(Path.of("in.txt"), "hello\n");
try (var reader = Files.newBufferedReader(Path.of("in.txt"));
var writer = Files.newBufferedWriter(Path.of("out.txt"))) {
writer.write(reader.readLine().toUpperCase());
}
IO.println(Files.readString(Path.of("out.txt")));
}Output:
HELLOYour own resource
Any class that implements AutoCloseable can be used in try:
class Connection implements AutoCloseable {
Connection() {
IO.println("open");
}
@Override
public void close() {
IO.println("close");
}
}
void main() {
try (var connection = new Connection()) {
IO.println("work");
throw new IllegalStateException("failed");
} catch (IllegalStateException e) {
IO.println("caught: " + e.getMessage());
}
}Output:
open
work
close
caught: failedNote the order: the resource is closed before the catch block runs.
Common mistake
Closing the resource manually at the end of try. If an exception happens earlier, close() is never called:
class Connection implements AutoCloseable {
@Override
public void close() {
IO.println("close");
}
}
void main() {
try {
var connection = new Connection();
Integer.parseInt("x");
connection.close();
} catch (NumberFormatException e) {
IO.println("error, connection left open");
}
}Output:
error, connection left openFunctions used in this recipe
- try / catch / finally — Catches exceptions; finally always runs, and try-with-resources closes resources for you.
- AutoCloseable — The interface of a resource that can be closed by try-with-resources.
- BufferedReader — Reads text line by line with buffering — the classic way to process large files.