Skip to content

Intermediate · Exceptions and generics · topic 28 of 60 · 20 min

try-with-resources and clean-up

Explanation

Files, network connections and database connections must be closed, or the program runs out of them. try-with-resources (try (Resource r = …) { … }) closes every resource automatically at the end of the block, in reverse order, even when an exception is thrown. Any class that implements AutoCloseable can be used this way.

Why closing matters

Operating systems and databases give each program a limited number of open files and connections. Forgetting to close them causes a resource leak: after a few hours a server starts failing with "Too many open files" or "connection pool exhausted". Closing must happen even when an error occurs halfway.

The old way: finally

java
java.io.BufferedReader reader = null;
try {
    reader = new java.io.BufferedReader(new java.io.FileReader("orders.csv"));
    System.out.println(reader.readLine());
} catch (java.io.IOException e) {
    System.out.println("Read failed: " + e.getMessage());
} finally {
    if (reader != null) {
        try { reader.close(); } catch (java.io.IOException ignored) { }
    }
}
Correct but long and easy to get wrong.

The modern way: try-with-resources (Java 7+)

java
import java.io.*;

try (BufferedReader reader = new BufferedReader(new FileReader("orders.csv"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    System.out.println("Read failed: " + e.getMessage());
}
// reader.close() has been called automatically here

Several resources can be opened in one try, separated by semicolons; they are closed in the REVERSE order of opening. The resource variable is final inside the block.

java
try (var in = new FileInputStream("photo.jpg");
     var out = new FileOutputStream("copy.jpg")) {
    in.transferTo(out);          // Java 9+
}                                 // out is closed first, then in

AutoCloseable: make your own resource

java
class Timer implements AutoCloseable {
    private final long start = System.nanoTime();
    private final String label;
    Timer(String label) { this.label = label; }
    @Override public void close() {
        System.out.printf("%s took %d ms%n", label, (System.nanoTime() - start) / 1_000_000);
    }
}
try (Timer t = new Timer("GST report")) {
    buildReport();
}   // prints "GST report took … ms" automatically

Suppressed exceptions

If the try block throws and then close() also throws, try-with-resources keeps the FIRST exception as the main one and attaches the close() exception to it as a suppressed exception (e.getSuppressed()). The old finally style would lose the first exception.

Careful: Opening a resource OUTSIDE the parentheses defeats the purpose: var conn = getConnection(); try { … } does not close conn. Put the creation inside try ( … ). In Java 9+ you may also list an existing effectively final variable: try (conn) { … }.
Think of it like this: try-with-resources is like a hotel key card that automatically stops working at checkout time, whether you left calmly or rushed out because of a fire alarm. You never have to remember to return it.
Tip: JDBC connections, statements and result sets, file streams, Scanner on files, and HTTP client responses are all AutoCloseable. Whenever you see one, reach for try-with-resources.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

try-with-resources and clean-up · 1/6

try-with-resources

In this lesson you will close files and connections safely with try-with-resources.

Prefer a video by a teacher? Find free videos on “java try with resources autocloseable explained” on YouTube ↗

In real life: A nightly report that crashed the server

A payroll server crashed every few days with "Too many open files". The report code opened a FileWriter for each employee and closed it only on success; whenever a record had bad data, the exception skipped the close. Switching to try-with-resources fixed the leak.

java
for (Employee e : employees) {
    try (var w = new java.io.FileWriter("slips/" + e.id() + ".txt")) {
        w.write(slipFor(e));
    } catch (java.io.IOException ex) {
        System.err.println("Slip failed for " + e.id() + ": " + ex.getMessage());
    }
}

Practice (0/3 done)

Task 1 · Question

try (A a = new A(); B b = new B()) { } — in which order are they closed?

Task 2 · Question

Which interface must a class implement to be used in try-with-resources?

Task 3 · Practice

Write a method static int countLines(String path) that counts the lines of a text file using BufferedReader in try-with-resources, and returns -1 (after printing a message) if an IOException happens. Test it with an existing file and a missing one.

Quick quiz

Question 1

1.What problem does try-with-resources solve?

Question 2

2.Since which Java version is try-with-resources available?

Question 3

3.What is a suppressed exception?

Question 4

4.var c = open(); try { use(c); } catch (Exception e) {} — is c closed automatically?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What problem does try-with-resources solve?

Answer: Forgetting to close resources, especially when exceptions happen

It closes automatically.

Since which Java version is try-with-resources available?

Answer: Java 7

Introduced in Java 7.

What is a suppressed exception?

Answer: An exception thrown by close() while another exception was already in flight

It is attached to the main exception.

var c = open(); try { use(c); } catch (Exception e) {} — is c closed automatically?

Answer: No, only resources declared in try ( … ) are closed

It must be declared in the resource specification (or listed there).

What happens to an exception nobody catches in main?Related

Answer: The thread ends and the stack trace is printed

Uncaught exceptions end the thread.

From Exceptions: try, catch and finally

A custom exception class should inherit from...Related

Answer: Exception

Custom exceptions derive from Exception (or a more specific exception).

From Exceptions: try, catch, finally and custom exceptions

When does the clean-up part of a context manager run?Related

Answer: Always, when the with block ends for any reason

That is the whole point: clean-up runs whether the block finished normally or raised an error.

From Context managers and the with statement

When does finally run?Related

Answer: Always, after try (and catch)

finally runs in every case, even after return.

From Error handling: try, catch, finally and throw

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next: Generics →

Next steps

  1. 2 more topics in “Exceptions and generics” before its exam: Generics, Avoiding NullPointerException.
  2. Module 6 exam: Exceptions and generics · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, The collections framework. 60 topics left in the course before the final exam.

← Previous: Checked vs unchecked exceptions and throwing your own