Prefer try-with-resources to try-finally in Java

When working with Java applications, Java libraries include many resources that must be closed manually by invoking close() method. Let us consider InputStream, OutputStream, java.sql.Connection, etc. In many cases, closing objects are often overlooked by clients. Many developers use finalizers as a safety net but it has performance issues.

From the very beginning, try-finally was the best way to guarantee a resource would be closed properly, even when facing exception or return. try-finally doesn’t look bad for a single resource.

Issues with try-finally

  • try-finally doesn’t scale well with the increase of resources required to be closed.
  • Nested try-finally blocks stick out ugly
  • try-finally is a bit tricky to get it right, even in JDK
  • Nested finally block is a bit complicated in case of debugging

try-with-resource with single resource

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

try-with-resource with multiple resources

static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
} catch (IOException e) {
    // do something here
}

Advantages try-with-resources

  • Shorter, more readable than try-finally
  • No exceptions are suppressed
  • try-finally is a bit tricky to get it right, even in JDK
  • Nested finally block is a bit complicated in case of debugging

Always prefer to use try-with-resources when working with resources that must be closed