///Use the Finally Keyword to Avoid Resource Leaks

Use the Finally Keyword to Avoid Resource Leaks

Use the finally keyword to avoid resource leaks

 

Editor’s note: The following articles are excerpts from the book "Practical Java" published by Addison-Wesley. You can order this book from the developerWorks Bookstore.

The finally keyword is the best addition to the Java exception handling model over other language’s models. The finally construct enables code to execute whether or not an exception occurred. Using finally is good to maintain the internal state of an object and to clean up non-memory resources. Without finally, your code is more convoluted. For example, the following is how you must write code to free non-memory resources without the benefit of finally:



import java.net.*;
import java.io.*;

class WithoutFinally
{
public void foo() throws IOException
{
//Create a socket on any free port
ServerSocket ss = new ServerSocket(0);
try {
Socket socket = ss.accept();
//Other code here...
}
catch (IOException e) {
ss.close(); //1
throw e;
}
//...
ss.close(); //2
}
}

This code creates a socket and calls the accept method. You must close the socket before exiting the method in order to avoid a resource leak. To do this, you call close as the last statement of the method at //2. What happens, however, if an exception occurs in the try block? In this case, the close call at //2 is not reached. Therefore, you must catch the exception and put in another call to close at //1 prior to rethrowing the exception. This ensures the socket is closed prior to exiting the method.

Writing code in this manner is bothersome and prone to error, yet necessary without the existence of finally. Unfortunately, in languages without a finally mechanism, programmers might forget to structure their code in this manner, leading to resource leaks. The finally clause in Java solves this problem. With finally, the previous code is rewritten as follows:



import java.net.*;
import java.io.*;

class WithFinally
{
public void foo2() throws IOException
{
//Create a socket on any free port
ServerSocket ss = new ServerSocket(0);
try {
Socket socket = ss.accept();
//Other code here...
}
finally {
ss.close();
}
}
}

A finally block ensures the close method is executed whether or not an exception is thrown from within the try block. Therefore, the close method is guaranteed to be called before the method exits. You are then sure the socket is closed and you have not leaked a resource. There is no longer any need to have a catch block in this method. The catch block in the first example was provided only to close the socket that is now closed with finally. If you did provide a catch block, the code in the finally block executes after the catch block finishes.

The finally block must be used in conjunction with a try or try/catch block. In addition, there is no way to exit a try block without executing its finally block. If the finally block exists, it always executes. (This statement is true for all intents and purposes. There is a way to exit a try block without executing the finally block. If the code executes a System.exit(0); from within a try block, the application terminates without the finally executing. On the other hand, if you unplug the machine during a try block, the finally will not execute either.)

2010-05-26T17:15:36+00:00 September 16th, 2003|Java|0 Comments

About the Author:

Leave A Comment