Java Exceptions – Handling Non-Initialized Objects in the Finally Block

exceptionsfinallyjava

I like using final variables whenever possible. Often those variables have to be closed afterwards. Note that I'm currently working on Java 6 so there is not closeable interface, but the same applies to later Java versions as well. For example:

final InputStream in;

try{
    in=new InputStream(...);
    //...
}catch(...) {}
finally{
    in.close(); //whoops!
}

At that point the IDE will point out that in might be uninitialized. Wrapping the close statement in an if like so

if(in!=null)
    in.close();

doesn't work either, despite null being the default value for uninitialized objects. My solution so far is to forget about declaring them final in the first place, and initializing them as null at declaration.

Another solution is to place the declaration and close statement in the try block:

try{
    final InputStream in=new InputStream(...);
    //...
    in.close();
}catch(InputStreamRelatedException) {};

which would leave in open (?) in case of non-InputStream related exception.

What is the preferred method?

Best Answer

You are running into difficulties because you are trying to handle two different cases with the same try-catch:

  • constructing the InputStream could fail, in which case you also can't close() anything.
  • using the InputStream could fail, in which case you need a close().

The solution is to separate these cases, and not instantiate the object in the same scope where it might be used:

final InputStream in;
try { in = new InputStream(); }
catch (...) { ... /* must throw or return, or assign to `in` */ }

try { doSomethingWith(in); }
catch (...) { ... }
finally { in.close(); }