Monday, October 13, 2014

Try-with-resources in Java 7

Try-with-resources in Java 7

Try-with-resources in Java 7 is a new exception handling mechanism that makes it easier to correctly close resources that are used within a try-catch block.

Resource Management With Try-Catch-Finally, Old School Style 

Managing resources that need to be explicitly closed is somewhat tedious before Java 7.
private static void printFile() throws IOException {
    InputStream input = null;

    try {
        input = new FileInputStream("file.txt");

        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }
    } finally {
        if(input != null){
            input.close();
        }
    }
}
The code marked in bold is where the code can throw an Exception. As you can see, that can happen in 3 places inside the try-block, and 1 place inside the finally-block.

The finally block is always executed no matter if an exception is thrown from the try block or not. That means, that the InputStream is closed no matter what happens in the try block. Or, attempted closed that is. TheInputStream's close() method may throw an exception too, if closing it fails.

 Try-with-resources

In Java 7 you can write the code from the example above using the try-with-resource construct like this:
private static void printFileJava7() throws IOException {

    try(FileInputStream input = new FileInputStream("file.txt")) {

        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }
    }
}
 Notice the first line inside the method:
try(FileInputStream input = new FileInputStream("file.txt")) {
This is the try-with-resources construct. The FileInputStream variable is declared inside the parentheses after the try keyword. Additionally, a FileInputStream is instantiated and assigned to the variable.
When the try block finishes the FileInputStream will be closed automatically. This is possible because FileInputStream implements the Java interface java.lang.AutoCloseable. All classes implementing this interface can be used inside the try-with-resources construct.

 If an exception is thrown both from inside the try-with-resources block, and when the FileInputStream is closed (when close() is called), the exception thrown inside the try block is thrown to the outside world. The exception thrown when the FileInputStream was closed is suppressed. This is opposite of what happens in the example first in this text, using the old style exception handling (closing the resources in the finally block).

Using Multiple Resources

You can use multiple resources inside a try-with-resources block and have them all automatically closed. Here is an example:
private static void printFileJava7() throws IOException {

  try(  FileInputStream input = new FileInputStream("file.txt");
      BufferedInputStream bufferedInput = new BufferedInputStream(input)
    ) {

        int data = bufferedInput.read();
        while(data != -1){
            System.out.print((char) data);
    data = bufferedInput.read();
        }
    }
}
This example creates two resources inside the parentheses after the try keyword. An FileInputStream and aBufferedInputStream. Both of these resources will be closed automatically when execution leaves the try block.
The resources will be closed in reverse order of the order in which they are created / listed inside the parentheses. First the BufferedInputStream will be closed, then the FileInputStream.

No comments:

Post a Comment

Distributed Transactions

What is a distributed transaction?  Transactions that span over multiple physical systems or computers over the network, are simply termed D...