The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Essential Java Classes
Lesson: Handling Errors with Exceptions

## The finally Block

> The final step in setting up an exception handler is providing a mechanism for cleaning up the state of the method before (possibly) allowing control to be passed to a different part of the program. You do this by enclosing the cleanup code within a `finally` block.

> The `try` block of the `writeList` method that you've been working with opens a `PrintWriter`. The program should close that stream before allowing control to pass out of the `writeList` method. This poses a somewhat complicated problem because `writeList`'s `try` block has three different exit possibilities:

> 1. The `new FileWriter` statement failed and threw an `IOException`.
> 2. The `victor.elementAt(i)` statement failed and threw an `ArrayIndexOutOfBoundsException`.
> 3. Everything succeeded and the `try` block exited normally.
> The runtime system always executes the statements within the `finally` block regardless of what happens within the `try` block. Regardless of whether control exits the `writeList` method's `try` block due to one of the three scenarios listed previously, the code within the `finally` block will be executed.

> This is the `finally` block for the `writeList` method. It cleans up and closes the PrintWriter.

> >     finally {
> >         if (out != null) {
> >             System.out.println("Closing PrintWriter");
> >             out.close();
> >         } else {
> >             System.out.println("PrintWriter not open");
> >         }
> >     }

### Is the finally Statement Really Necessary?

> At first the need for a `finally` statement may not be immediately apparent. Programmers often ask "Is the `finally` statement really necessary or is it just sugar for my Java?" In particular, C++ programmers doubt the need for a `finally` statement because C++ doesn't have one.

> The need for a `finally` statement is not apparent until you consider the following: how does the `PrintWriter` in the `writeList` method get closed if you don't provide an exception handler for the `ArrayIndexOutOfBoundsException` and an `ArrayIndexOutOfBoundsException` occurs? (It's easy and legal to omit an exception handler for `ArrayIndexOutOfBoundsException` because it's a runtime exception and the compiler won't alert you that the `writeList` contains a method call that might throw one.) The answer is that the `PrintWriter` does not get closed if an `ArrayIndexOutOfBoundsException` occurs and `writeList` does not provide a handler for it--unless the `writeList` provides a `finally` statement.

> There are other benefits to using the `finally` statement. In the `writeList` example it is possible to provide for cleanup without the intervention of a `finally` statement. For example, you could put the code to close the `PrintWriter` at the end of the `try` block and again within the exception handler for `ArrayIndexOutOfBoundsException`, as shown here:

> >     try {
> >         . . .
> >         out.close();       // don't do this; it duplicates code
> >     } catch (ArrayIndexOutOfBoundsException e) {
> >         out.close();       // don't do this; it duplicates code
> >         System.err.println("Caught ArrayIndexOutOfBoundsException: "
> >                            + e.getMessage());
> >     } catch (IOException e) {
> >         System.err.println("Caught IOException: " + e.getMessage());
> >     }

> However, this duplicates code, making the code hard to read and prone to errors if you modify the code later. For example, if you add code to the `try` block that may throw a new type of exception, you will have to remember to close the `PrintWriter` within the new exception handler (which if you're anything like me, you are bound to forget).

| Start of Tutorial > Start of Trail > Start of Lesson | Search