Thefinally
block always executes when thetry
block exits. This ensures that thefinally
block is executed even if an unexpected exception occurs. Butfinally
is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by areturn
,continue
, orbreak
. Putting cleanup code in afinally
block is always a good practice, even when no exceptions are anticipated.
Note: If the JVM exits while thetry
orcatch
code is being executed, then thefinally
block will not execute. Likewise, if the thread executing thetry
orcatch
code is interrupted or killed, thefinally
block will not execute even though the application as a whole continues.The
try
block of thewriteList
method that you've been working with here opens aPrintWriter
. The program should close that stream before exiting thewriteList
method. This poses a somewhat complicated problem becausewriteList
'stry
block can exit in one of three ways.The runtime system always executes the statements within the
- The
new FileWriter
statement fails and throws anIOException
.- The
vector.elementAt(i)
statement fails and throws anArrayIndexOutOfBoundsException
.- Everything succeeds and the
try
block exits normally.finally
block regardless of what happens within thetry
block. So it's the perfect place to perform cleanup.The following
finally
block for thewriteList
method cleans up and then closes thePrintWriter
.In thefinally { if (out != null) { System.out.println("Closing PrintWriter"); out.close(); } else { System.out.println("PrintWriter not open"); } }writeList
example, you could provide for cleanup without the intervention of afinally
block. For example, you could put the code to close thePrintWriter
at the end of thetry
block and again within the exception handler forArrayIndexOutOfBoundsException
, as follows.However, this duplicates code, thus making the code difficult to read and error-prone should you modify it later. For example, if you add code that can throw a new type of exception to thetry { out.close(); //Don't do this; it duplicates code. } catch (FileNotFoundException e) { out.close(); //Don't do this; it duplicates code. System.err.println("Caught: FileNotFoundException: " + e.getMessage()); throw new RuntimeException(e); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); }try
block, you have to remember to close thePrintWriter
within the new exception handler.
Important: Thefinally
block is a key tool for preventing resource leaks. When closing a file or otherwise recovering resources, place the code in afinally
block to ensure that resource is always recovered.