Java: Cleaning up after yourself

Most sensible Java programmers know that garbage collection is no substitute for careful de-allocation of resources. In Java that a class typically allows you to do this on a per object basis with the close method. On .net, this the equivalent is the dispose method.

Clean up is also not an easy task because a method could return from multiple places and exceptions can be thrown from anywhere.

Take for instance the following code that writes a line to a file:

final PrintWriter pw = new PrintWriter("hello.txt");
pw.println("Hello world");
pw.close();

It’s quite straight forward: Open a file, write to the file, close the file. Cleanup is taken care of right?

Not really. Any of the three lines could potentially throw an exception. The first line in particular throws the checked FileNotFoundException.

Java provides the try, catch and finally keywords to deal with problem.

So how about this?

try {
  final PrintWriter pw = new PrintWriter("hello.txt");
  pw.println("Hello world");
} catch (final FileNotFoundException e) {
  // log error
} finally {
  pw.close();
}

Unfortunately it doesn’t compile because pw is out of scope in the finally clause so pw.close() is a compile error.

So we try again, this time having two try blocks: One for the close operation and another for catching the exception:

try {
  final PrintWriter pw = new PrintWriter("hello.txt");
  try {
    pw.println("Hello world");
  } finally {
    pw.close();
  }
} catch (final FileNotFoundException e) {
  // log exception
  throw e;
}

For each new resource we want to open and then access together, we need a new try and finally block and potentially a new try and catch block:

try {
  final PrintWriter pw1 = new PrintWriter("hello.txt");
  try {
    final PrintWriter pw2 = new PrintWriter("hello.txt");
    try {
      pw1.println("Hello world");
      pw2.println("Hello world");
    } finally {
      pw2.close();
    }
  } finally {
    pw1.close();
  }
} catch (final FileNotFoundException e) {
  // log exception
  throw e;
}

If a large number of resources need to be opend simultaneously, it can be help to create a class to help close all resources.

public class Disposer {
  ...

  public <T extends Closeable> T disposes(
      final T closeable);

  public void dispose();
}

The disposes method registers the closeable object with the disposer object. The dispose method will call close on all registered objects in reverse order. The implementation is left to the reader as an exercise.

This class will allow us to use only one try block for everything:

final Disposer disposer = new Disposer();

try {
  final PrintWriter pw1 = disposer.disposes(new PrintWriter("hello.txt"));
  final PrintWriter pw2 = disposer.disposes(new PrintWriter("hello.txt"));
  pw1.println("Hello world");
  pw2.println("Hello world");
} catch (final FileNotFoundException e) {
  // log exception
  throw e;
} finally {
  disposer.dispose();
}

The code is much shorter and more readable.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s