Ushanka

Sunday, February 3, 2008

When goodbyes aren't enough...

The Java core classes have a pretty nasty habit of throwing IOExceptions in close methods. Since IOExceptions are not derived from RuntimeException, you either have to catch them or declare them as thrown from the method calling close. Now, suppose I have a class that holds a couple of resources, r1 and r2. Let's see what happens if I try to release them together:

try
{
r1.close();
r2.close();
}
catch(IOException e)
{
// Do whatever I need to here...
}

If r1's close happens to throw, r2's close will never be called and I might (in a long-running application) leak resources. The same problem occurs if I don't bother catching the exception and declare it thrown from my method. Putting the close calls in the finally clause won't fix the problem either. A working solution could be:

try
{
r1.close();
}
catch(IOException e)
{
// Do whatever I need to here...
}
try
{
r2.close();
}
catch(IOException e)
{
// Do whatever I need to here...
}

This code looks worse than checking for return codes! What's more, I, as a programmer, am getting rid of a resource. I have decided that the given resource is no longer of any use to me. I am throwing it away. And it's coming back!

I can't think of a single reason an exception (checked or unchecked) should be thrown from a method that is releasing a resource. In situations like this, a return code should be used instead of exceptions because the programmer has, by the very act of calling your method, declared that she is no longer interested in the resource.

Labels: ,