Prefer try-with-resources to try-finally

The Java libraries include many resources that must be closed manually by invoking a close method. Examples include InputStream, OutputStream, and java.sql.Connection.  While many of these resources use finalizers as a safety net, finalizers don’t work very well. 

For a long time, a try-finally statement was the best way to guarantee that a resource would be closed properly, even in the face of an exception or return.

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

The above statement may not appear wrong, but it gets worse when you add a second resource. Most of the programmers are doing this on a daily basis. The code in both the try block and the finally block is capable of throwing exceptions.

For example, in the firstLineOfFile method, the call to readLine could throw an exception due to a failure in the underlying physical device, and the call to close could then fail for the same reason. Under these circumstances, the second exception completely wipe out the first one. There is no record of the first exception in the exception stack trace, which can greatly complicate debugging in real systems—usually it’s the first exception that you want to see in order to diagnose the problem. 

All of these problems were solved in one fell swoop when Java 7 introduced the try-with-resources statement. To be usable with this construct, a resource must implement the AutoCloseable interface, which consists of a single void-returning close method. If you write a class that represents a resource that must be closed, your class should implement AutoCloseable too.

Using try-with-resources:

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

Not only are the try-with-resources versions shorter and more readable than the originals, but they provide far better log trace. As you can see in method   firstLineOfFile. If exceptions are thrown by both the readLine call and the (invisible) close, the latter exception is forcibly put an end to in favor of the former. In fact, multiple exceptions may be suppressed in order to preserve the exception that you actually want to see.

You can add catch clauses on try-with-resources statements, just as you can on regular try-finally statements. One of the use case is shown below. 

i.e. We can also write above method firstLineOfFile like below. Method    firstLineOfFile that does not throw exceptions, but takes a default value to return if it can’t open the file or read from it:

static String firstLineOfFile(String path, String defaultVal) {
       try (BufferedReader br = new BufferedReader(
         new FileReader(path))) {
            return br.readLine();
       } catch (IOException e) {
          return defaultVal;
       }
}

The lesson is clear: Always use try-with-resources over try-finally when working with resources that must be closed. The resulting code is shorter and clearer and the exceptions that it generates are more useful. The try-with-resources statement makes it easy to write correct code using resources that must be closed, which was practically impossible using try-finally.