Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Java: How to use the finally keyword to avoid resource leaks

In this article we will discuss about the finally keyword and its usage in Java.

Introduction:

The ‘finally’ keyword is a part of try/catch block. But it has significant importance from memory management point of view. This article will not discuss about the normal flow of exception handling but it will explain the implementation of ‘finally’ keyword to prevent memory leak.

The finally keyword is an integral part of java exception handling mechanism. The finally block ensures that the JVM will execute the code written within it even if there is an exception in the code. The finally construct helps to maintain the initial state of the object and to clean up the non memory resources. Normally a finally block is used to ensure the following:

  • An Input Output stream is closed
  • A database connection is closed

Both of these scenarios lead to memory or resource leaks if they are not closed. The finally is useful for more than just exception handling, it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. It is always a good practice to put the cleanup code within a finally block, even when no exceptions are anticipated.

Usage:

Let us consider the following code:

Listing 1: Sample code without finally block

import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.ObjectOutputStream ;
import java.text.DateFormat ;
import java.text.ParseException ;
import java.text.SimpleDateFormat ;
import java.util.Date ;

import com.home.markerDemo.Employee ;

public class SerializeDemo {

	public SerializeDemo () {
	}

	public static void main( String [] args ) {
		Employee employee = new Employee () ;
		employee.setFirstName( " John " ) ;
		employee.setLastName( " Smith " ) ;
		employee.setDepartment( " Technical " ) ;
		employee.setEcode( 1234 );
		try {
			String dojStr = " 1971-07-15 " ;
			DateFormat df = new SimpleDateFormat ( " yyyy-MM-dd " ) ;
			Date dojDate = null ;
			dojDate = df.parse ( dojStr ) ;

			employee.setDateOfJoining( dojDate ) ;
			FileOutputStream fileOut = new FileOutputStream ( " employee.ser " ) ;
			ObjectOutputStream out = new ObjectOutputStream ( fileOut ) ;
			out.writeObject ( employee ) ;
			out.close () ;
			fileOut.close () ;
		} catch ( IOException i ) {
			i.printStackTrace () ;
		} catch ( ParseException e ) {
			e.printStackTrace () ;
		}
	}

}

As we can see here the Object output stream and File Output stream are closed within the try block. So in case there is an exception in the following line code:

	out.writeObject ( employee );

The code will terminate at this point. The control will move to the exception block and these two objects will remain open for ever. This will lead to resource leakage. Now let’s change the above code as under:

Listing 2: Sample code with finally block

import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.ObjectOutputStream ;
import java.text.DateFormat ;
import java.text.ParseException ;
import java.text.SimpleDateFormat ;
import java.util.Date;

import com.home.markerDemo.Employee ;

public class SerializeDemo {

	public SerializeDemo () {
	}

	public static void main ( String [] args ) {
		Employee employee = new Employee () ;
		employee.setFirstName ( " John " ) ;
		employee.setLastName ( " Smith " ) ;
		employee.setDepartment ( " Technical " ) ;
		employee.setEcode ( 1234 ) ;
		FileOutputStream fileOut = null ;
		ObjectOutputStream out = null ;
		try {
			String dojStr = " 1971-07-15 " ;
			DateFormat df = new SimpleDateFormat ( " yyyy-MM-dd " ) ;
			Date dojDate = null ;
			dojDate = df.parse ( dojStr ) ;

			employee.setDateOfJoining ( dojDate ) ;
			fileOut = new FileOutputStream ( " employee.ser " ) ;
			out = new ObjectOutputStream ( fileOut ) ;
			out.writeObject ( employee ) ;
		} catch ( IOException i ) {
			i.printStackTrace () ;
		} catch ( ParseException e ) {
			e.printStackTrace () ;
		} finally {
			try {
				out.close () ;
				fileOut.close () ;
			} catch ( IOException e ) {
				e.printStackTrace () ;
			}
		}
	}
}

The above piece of code is exactly the same as the earlier version except for the fact that the resources Object Output stream and File Output Stream are closed within a finally block. This ensures that even if there is an exception while executing:

out.writeObject ( employee );

The Object Output Stream and the File Output Stream are closed. This code is much more reliable as this ensures that there is no resource leakage.

The finally block ensures the close method is executed whether or not an exception is thrown from within the try block. Thus, the close method is guaranteed to be called before the method exits. As a developer we are then sure that both the file output stream and the object output stream are closed. Thus there is no possibility of a resource leakage. In a situation where the exception has occurred the finally block executes after the catch block is executed. In case there is no exception, the finally block is execute right after the try block thus ensuring that the resources are released.

The finally block must be used in conjunction with a try or try/catch block. In fact, there is no way to exit a try block without executing it’s finally block. If the finally block exists, it always executes. If the code executes System.exit (0), then the code will exit without executing the finally block in all other situations the finally block is execute without fail.

How to Use the finally block:

Approach 1

If a method throws all the exception, then it is advised to use the finally block without any catch block.

Listing 3: A normal try and finally block

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public final class SimpleFinally {

	public static void main(String... aArgs) throws IOException {
		simpleFinally(" C:\\Temp\\test.txt ");
	}

	private static void simpleFinally(String aFileName) throws IOException {

		BufferedReader reader = new BufferedReader(new FileReader(aFileName));
		try {
			// Any exception in the try block will cause the finally block to
			// execute
			String line = null;
			while ((line = reader.readLine()) != null) {
				// logic to process the line...
			}
		} finally {
			reader.close();
		}
	}
}

Approach 2:

If a method handles all of the checked exceptions which could be thrown from its implementation, then we can use a nested a try..finally block within a try..catch block. This approach becomes useful when they finally block also throws the same exceptions as the rest of the code. This behavior is commonly used in case of io operations. Though this approach looks slightly complicated, but is the better approach when compared to other approaches:

Listing 4: Using the try ... finally within a try ... catch block

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Logger;

public final class NestedFinally {

	public static void main(String... aArgs) {
		nestedFinally("C:\\Temp\\test.txt");
	}

	private static void nestedFinally(String aFileName) {
		try {
			
			BufferedReader reader = new BufferedReader( new FileReader ( aFileName ) );
			try {
				String line = null;
				while ((line = reader.readLine()) != null) {
					// logic to process the line...
				}
			} finally {
				
				reader.close();
			}
		} catch (IOException ex) {
			fLogger.severe("Problem occured : " + ex.getMessage());
		}
	}

	private static final Logger fLogger = Logger.getLogger(NestedFinally.class
			.getPackage().getName());
}

Approach 3:

This is the traditional approach using the try ... catch ... finally as explained in Listing 2.

Conclusion:

We have already discussed different approaches in try-catch-finally block. The ‘finally’ keyword is generally considered to be a part of try-catch block. But it has other significant implementations also. As we all know memory leak is a major issue in application programming. So preventing memory leak is considered to be an important aspect in design. The power of ‘finally’ keyword is used in this area also. To conclude the discussion we can keep the following points in mind.

  • The finally block ensures that the code written within it will execute even when there is an exception
  • Finally block can be used as try ... finally or try ... catch ... finally


Website: www.techalpine.com Have 16 years of experience as a technical architect and software consultant in enterprise application and product development. Have interest in new technology and innovation area along with technical...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login