Performing cleanup with finally | CodeGuru

Performing cleanup with finally

Bruce Eckel’s Thinking in Java Contents | Prev | Next with finally There’s often some piece of code that you want to execute whether or not an exception occurs in a try block. This usually pertains to some operation other than memory recovery (since that’s taken care of by the garbage collector). To achieve this […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
4 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

with
finally

There’s


often some piece of code that you want to execute whether or not an exception


occurs in a


try

block. This usually pertains to some operation other than memory recovery


(since that’s taken care of by the garbage collector). To achieve this


effect, you use a

finally
clause
[44]
at the end of all the exception handlers. The full picture of an
exception-handling section is thus: try

{

// The guarded region:

// Dangerous stuff that might throw A, B, or C

}
catch
(A
a1) {

// Handle A

}
catch
(B b1) {

// Handle B

}
catch
(C c1) {

// Handle C

}
finally
{

// Stuff that happens every time

}

To


demonstrate that the


finally

clause always runs, try this program:

//: FinallyWorks.java
// The finally clause is always executed
 
public class FinallyWorks {
  static int count = 0;
  public static void main(String[] args) {
    while(true) {
      try {
        // post-increment is zero first time:
        if(count++ == 0)
          throw new Exception();
        System.out.println("No exception");
      } catch(Exception e) {
        System.out.println("Exception thrown");
      } finally {
        System.out.println("in finally clause");
        if(count == 2) break; // out of "while"
      }
    }
  }
} ///:~ 

This


program also gives a hint for how you can deal with the fact that exceptions in


Java (like exceptions in C++) do not allow you to resume back to where the


exception was thrown, as discussed earlier. If you place your


try

block in a loop, you can establish a condition that must be met before you


continue the program. You can also add a


static

counter or some other device to allow the loop to try several different


approaches before giving up. This way you can build a greater level of


robustness into your programs.

The


output is:

Exception thrown
in finally clause
No exception
in finally clause

Whether


an exception is thrown or not, the


finally

clause is always executed.


What’s
finally for?

In


a language without garbage collection


and

without automatic

destructor
calls,
[45]
finally
is important because it allows the programmer to guarantee the release of
memory regardless of what happens in the try
block. But Java has garbage collection, so releasing memory is virtually never
a problem. Also, it has no destructors to call. So when do you need to use
finally
in Java?
finally

is necessary when you need to set something


other

than memory back to its original state. This is usually something like an open


file or network connection, something you’ve drawn on the screen or even


a switch in the outside world, as modeled in the following example:

//: OnOffSwitch.java
// Why use finally?
 
class Switch {
  boolean state = false;
  boolean read() { return state; }
  void on() { state = true; }
  void off() { state = false; }
}
 
public class OnOffSwitch {
  static Switch sw = new Switch();
  public static void main(String[] args) {
    try {
      sw.on();
      // Code that can throw exceptions...
      sw.off();
    } catch(NullPointerException e) {
      System.out.println("NullPointerException");
      sw.off();
    } catch(IllegalArgumentException e) {
      System.out.println("IOException");
      sw.off();
    }
  }
} ///:~ 

The


goal here is to make sure that the switch is off when


main( )

is completed, so


sw.off( )

is placed at the end of the try block and at the end of each exception handler.


But it’s possible that an exception could be thrown that isn’t


caught here, so


sw.off( )

would


be missed. However, with


finally

you can place the closure code from a try block in just one place:

//: WithFinally.java
// Finally Guarantees cleanup
 
class Switch2 {
  boolean state = false;
  boolean read() { return state; }
  void on() { state = true; }
  void off() { state = false; }
}
 
public class WithFinally {
  static Switch2 sw = new Switch2();
  public static void main(String[] args) {
    try {
      sw.on();
      // Code that can throw exceptions...
    } catch(NullPointerException e) {
      System.out.println("NullPointerException");
    } catch(IllegalArgumentException e) {
      System.out.println("IOException");
    } finally {
      sw.off();
    }
  }
} ///:~ 

Here


the


sw.off( )

has been moved to just one place, where it’s guaranteed to run no matter


what happens.

Even


in cases in which the exception is not caught in the current set of


catch

clauses,


finally

will be executed before the exception-handling mechanism continues its search


for a handler at the next higher level:

//: AlwaysFinally.java
// Finally is always executed
 
class Ex extends Exception {}
 
public class AlwaysFinally {
  public static void main(String[] args) {
    System.out.println(
      "Entering first try block");
    try {
      System.out.println(
        "Entering second try block");
      try {
        throw new Ex();
      } finally {
        System.out.println(
          "finally in 2nd try block");
      }
    } catch(Ex e) {
      System.out.println(
        "Caught Ex in first try block");
    } finally {
      System.out.println(
        "finally in 1st try block");
    }
  }
} ///:~ 

The


output for this program shows you what happens:

Entering first try block
Entering second try block
finally in 2nd try block
Caught Ex in first try block
finally in 1st try block

The


finally

statement will also be executed in situations in which


break

and


continue

statements are involved. Note that, along with the labeled


break

and labeled


continue

,


finally

eliminates the need for a


goto

statement


in Java.


Pitfall:
the lost exception

In


general, Java’s exception implementation is quite outstanding, but


unfortunately there’s a flaw. Although exceptions are an indication of a


crisis in your program and should never be ignored, it’s possible for an


exception to simply be

lost.
This happens with a particular configuration using a
finally
clause:
//: LostMessage.java
// How an exception can be lost
 
class VeryImportantException extends Exception {
  public String toString() {
    return "A very important exception!";
  }
}
 
class HoHumException extends Exception {
  public String toString() {
    return "A trivial exception";
  }
}
 
public class LostMessage {
  void f() throws VeryImportantException {
    throw new VeryImportantException();
  }
  void dispose() throws HoHumException {
    throw new HoHumException();
  }
  public static void main(String[] args)
      throws Exception {
    LostMessage lm = new LostMessage();
    try {
      lm.f();
    } finally {
      lm.dispose();
    }
  }
} ///:~ 

The


output is:

A trivial exception
        at LostMessage.dispose(LostMessage.java:21)
        at LostMessage.main(LostMessage.java:29)

You


can see that there’s no evidence of the


VeryImportantException

,


which is simply replaced by the


HoHumException

in the


finally

clause. This is a rather serious pitfall, since it means that an exception can


be completely lost, and in a far more subtle and difficult-to-detect fashion


than the example above. In contrast, C++ treats the situation in which a second


exception is thrown before the first one is handled as a dire programming


error. Perhaps a future version of Java will repair the problem. (The above


results were produced with Java 1.1.

)
[44]

C++ exception handling does not have the


finally

clause because it relies on destructors to accomplish this sort of cleanup.

[45]

A destructor is a function that’s always called when an object becomes


unused. You always know exactly where and when the destructor gets called. C++


has automatic destructor calls, but Delphi’s Object Pascal versions 1 and


2 do not (which changes the meaning and use of the concept of a destructor for


that language).

Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.