Try-with-resources in JDK7 without scoped declarations

26 September 2011, by: Jan Beernink

A handy new feature in JDK7 is the try-with-resources statement. This statement is meant to eliminate a lot of the boilerplate code required for managing InputStreams and OutputStreams. Say for example, that I would want to copy the contents of an InputStream to an OutputStream. This would require the following code only to manage the in- and output stream:

InputStream in = createInputStream();
try {
   OutputStream out = createOutputStream();
   try {
      /* Copy data here */
   } finally {
      try {
         out.close();
      } catch(IOException e) {
         //Prevent this exception from suppressing actual exception
      }
   }
} finally {
   try {
      in.close();
   } catch(IOException e) {
      //Prevent this exception from suppressing actual exception
   }
}

Using the new try-with-resources statement, the above code can be rewritten as the following:

try (InputStream in = createInputStream(); OutputStream out = 
      createOutputStream()) {
   /* Copy data here */
}

The InputStream and OutputStream are automatically closed at the end of the try-with-resources block. If an exception is thrown during the main block and then again during the closing of one (or both) of the streams, the exception on the close operation is added to the original exception as a suppressed exception, so no exceptions are swallowed silently anymore. The try-with-resources blocks are also not limited to be used for in- and output streams, but can be used on any object that implements the AutoCloseable interface.

There is one minor disadvantage to the try-with-resource statement, it is required to define the variable that refers to the object to be closed within the brackets after the try. For example, if you have a method that receives an InputStream as a parameter, the Java compiler would not allow you to do this:

public void readData(InputStream in) {
   try(in) {
      int input;
      while((input = in.read()) >=0) {
         //Use input here
      }
   }
}

The above code would produce a compiler error as no variable has been defined between the brackets of the try-with-resources statement. I would propose the following workaround for this situation:

public void readData(InputStream in) {
   try(InputStream autoCloseableInputStream = in) {
      int input;
      while((input = in.read()) >=0) {
         //Use input here
      }
   }
}

 


This code does compile and the stream is automatically closed at the end of the try block. Since the autoCloseableInputStream and in variables refer to the exact same object, it is not necessary to actually use the autoCloseableInputStream variable in the code. Using a name like autoCloseableInputStream makes it clear that this variable is only defined in order to be able to use the try-with-resources statement.

2 comments to “Try-with-resources in JDK7 without scoped declarations”

  1. Riyad Kalla says:

    Great, quick concise writeup on try-with.

    I actually *like* that the argument has to be defined in the try-block, as it makes it painfully hard to write a method that takes a stream as an argument, does something with it and then closes it before returning (not letting the caller know it closed it out from under it).

    I am thinking about that from an API design standpoint though, I can understand there are scenarios where that might work, but for my purposes I think that was a good (err on the side of caution) design decision by the spec team.

  2. Thierry BODHUIN says:

    While your code is correct, I believe that it should not be used normally, the closing of resource should be done normally in the scope where this resource has been created. The method readData should normally return an Exception and if captured in the caller code (that created the InputStream) then the try catch should close the resource.

    It is the same problem as where to catch the Exception and how to deal with them.

Type your comment below:

Time limit is exhausted. Please reload CAPTCHA.

css.php best counter