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
The
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:- The
new FileWriter
statement failed and threw anIOException
. - The
victor.elementAt(i)
statement failed and threw anArrayIndexOutOfBoundsException
. - Everything succeeded and the
try
block exited normally.
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 afinally
statement may not be immediately apparent. Programmers often ask "Is thefinally
statement really necessary or is it just sugar for my Java?" In particular, C++ programmers doubt the need for afinally
statement because C++ doesn't have one.The need for afinally
statement is not apparent until you consider the following: how does thePrintWriter
in thewriteList
method get closed if you don't provide an exception handler for theArrayIndexOutOfBoundsException
and anArrayIndexOutOfBoundsException
occurs? (It's easy and legal to omit an exception handler forArrayIndexOutOfBoundsException
because it's a runtime exception and the compiler won't alert you that thewriteList
contains a method call that might throw one.) The answer is that thePrintWriter
does not get closed if anArrayIndexOutOfBoundsException
occurs andwriteList
does not provide a handler for it--unless thewriteList
provides afinally
statement.
There are other benefits to using thefinally
statement. In thewriteList
example it is possible to provide for cleanup without the intervention of afinally
statement. For example, you could put the code to close thePrintWriter
at the end of thetry
block and again within the exception handler forArrayIndexOutOfBoundsException
, as shown here:
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 thetry { . . . 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()); }try
block that may throw a new type of exception, you will have to remember to close thePrintWriter
within the new exception handler (which if you're anything like me, you are bound to forget).
No comments:
Post a Comment