Java News Brief        
                                          May 2000 Issue                                        

Headlines: 
Java Technical Insight of the Month
    
An integral part of exception handling:  finally
Visit  The Java News Brief Archive for past issues of the JNB.
OCI Educational Services
       
                
Java Technical Insight of the Month
An integral part of exception handling:  finally
By Paul King, Senior Software Engineer, Object Computing, Inc. (OCI)

Synopsis

For Java developers, the try-catch block is a way of life.  A fundamental part of this mechanism is the "finally" block.

As the name suggests, code in a finally block is always executed last, after all code in a corresponding try-catch block has executed.  This means that code in the finally block will run once immediately after one of the following occurs:

the try block completes execution without throwing an exception
the try block throws an exception that is not handled by a corresponding catch block
a corresponding catch block completes execution

This article focuses on the technical details of the finally block, and situations where it can be put to good use.

The mechanics of the finally block

A finally can appear optionally at the end of a try-catch block as shown:

try {
   
         // Normal processing
}
catch ( Exception e ) {
   
        
// Exception handling
}
finally {
       // Always executed once after all code in try-catch blocks completes
}

The code in a finally block is always executed once.  Its’ execution begins as a result of one of the following 3 conditions:

  1. The try block completes without an exception being thrown.  This occurs when the last statement in the try block completes, when a flow control statement like break or continue is encountered (provided they are associated with a loop controlled outside the try block), or a return is executed.
  2. The try block throws an unhandled exception.  In other words, there is no catch block associated with the exception that was thrown.
  3. A catch block completes execution, even as a result of (another) exception being thrown from within the catch block.

So, finally will be executed once if no exceptions occurred in the try block, or if multiple exceptions occurred in the try-catch blocks.

The try-catch paradigm exists in C++, but that language does not support finally.  The C++ destructor can serve a similar purpose as the finally block in Java.  However, for those of you who know C++, it should be clear that they are quite different animals.

When to use finally

Finally blocks are useful when you want to make sure that particular processing always happens prior to completing a method or block of code in a method.  To accomplish this in many other languages, multiple lines of redundant code are often necessary.  Such redundant code can be prevalent when attempting to handle errors.  Such redundancies can obscure the fundamentals of the processing, and are a ripe source of programming errors.

Error handling often involves freeing or releasing shared resources such as sockets, CORBA objects, database connections, files, and performing other clean-up operations.

The example below demonstrates how finally can be used to ensure that a socket obtained from a group (or pool) of sockets is released upon completion of a transaction.  By placing the release of the socket in the finally block, we are guaranteed that the resource will be freed for subsequent use.  Even if an exception that we do not handle occurs in the try block, or if an exception is thrown while executing a catch block, the release will still occur.  The finally block provides a convenient means to buttress the try-catch with a defensive block to perform clean-up that needs to occur, whether we complete the transaction normally, or fail as a result of an error.  We also include logging a diagnostic message in our finally block, since it is a convenient place to update an audit-trail.

NOTE: For the sake of brevity, the definition of the class that implements the socket pool (the pool member variable shown below), a member of the pool (the PooledSocket class shown below), and a file logging utility (the log member shown below) are not included with this example.  These classes may be included in a future article.

 

/** Writes request to a shared socket in a pool and places the reply in
  *  response. Reply will not exceed the capacity of response.
 */
void performTransaction(StringBuffer request, StringBuffer response)
   
throws InterruptedIOException, IOException, InterruptedException {

   
PooledSocket s=null; // This is the shared resource
   
String diagMessage="An exception occurred."; // Default diagnostic message

   
response.setLength(0); // Initialize to empty

   
try {
   
             s=pool.acquireSocket(); // If all sockets are busy, this will block
   
             s.write(request);
   
             s.read(response);
   
             diagMessage=response.toString();
   
}
   
catch ( InterruptedIOException e ) {
   
             throw e; // finally will execute before the exception is passed along
   
}
   
catch ( InterruptedException e ) {
   
             throw e; // finally will execute before the exception is passed along
   
}
   
catch ( IOException e ) {
   
             throw e; // finally will execute before the exception is passed along
   
}
   
finally {
   
      pool.releaseSocket(s); // Release to the pool for subsequent use
   
      log("performTransaction", request.toString(), diagMessage);
   
}
}


Complications

One must be careful if completion of a try-catch block occurs as a result of executing a return.  If a finally block also returns a value, then that return supercedes any previous return in the try-catch block.  Also, if an exception was thrown in the try or catch blocks that was not caught, then execution of a return in the finally block prevents the exception from being thrown to caller (because it is not possible for the caller to simultaneously evaluate the return and catch the exception).

Similarly, if an exception was throw in the try-catch block, an exception thrown in the finally block will supercede the prior exception.

Due to these complications, it is probably a good idea to avoid returning a value or purposely throwing an exception in a finally block.

Summary

When implementing a try-catch block, consider the following:

A finally block always executes once after the code in the corresponding try-catch block completes.
A return executed in the finally block takes precedence over one executed in the corresponding try-catch block and over passing an exception along to the caller.
A exception thrown in a finally block takes precedence over one thrown in the corresponding try-catch block.
The finally block is a good place for releasing shared resources, defensive code, and audit trail logging.


OCI Educational Services               

OCI has one of the most comprehensive OO training curriculums in the country.  Clients contract group training that is either taught at the client site or at an OCI Education Center in Tempe, AZ or St. Louis, MO.  We encourage you to check our our Object-Oriented Technology Curriculum show below:   (click on course titles for online descriptions)  

C Programming Java Syntax for Non-C Programmers Introduction to Java Object-Oriented Analysis and Design Object-Oriented Concepts Introduction to C++ for Non-C Programmers Object-Oriented Programming and C++ Java Programming Developing Graphical User Interfaces using Java JavaBeans Programming Advanced Java Programming CORBA Programming Introduction to CORBA Data Structures and Programming Techniques in C/C++ TAO's Implementation of CORBA Selected Topics in Object-Oriented Programming Using the ADAPTIVE Communication Environment C++ Framework Advanced C++ Developing Microsoft Windows Applications in Visual C++ and MFC

For more information or to register, email training.


Object Computing, Inc. is a Sun Authorized Java Center in St. Louis and a Member of the Object Management Group, OMG.  OCI specializes in distributed computing using object-oriented and web-enabled technologies and provides Consulting, Education, and Product Development services to clients nation-wide.  For more information contact us at 314-579-0066 (St. Louis), 480-752-0042 (Tempe) or email info.

For Information on Employment Opportunities
Click here OCI CAREER OPPORTUNITIES or email hr.


The Java News Brief is a monthly newsletter.  The purpose and intent of this publication is to advance Java, provide technical value, and to announce available OCI Java services.  If you would prefer to not receive this newsletter or would like to subscribe please email JNB and enter SUBSCRIBE or UNSUBSCRIBE within the Subject line.

Copyright (c) 2000.  Object Computing, Inc.   All rights reserved.   Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.  Object Computing, Inc. is independent of Sun Microsystems, Inc.