try-with-resources in Java 7

Java 7 has brought some very good features for lazy java developers. Try-with-resources is one of such feature which cuts line of code and also make the code more robust. In this tutorial, I will discuss things around this feature.

java 7 features

Sections in this post:

The old way of resource cleanup (Before java 7)
The new fancy way with try-with-resources (syntax example)
How actually it works?
Adding functionality to custom resources
Final notes

The old way of resource cleanup (Before java 7)

We have been doing this from long time. e.g. read a file from file system. Code may look different but flow will be like below example:

public class ResourceManagementBeforeJava7 
{
	public static void main(String[] args) 
	{
		BufferedReader br = null;
		try 
		{
			String sCurrentLine;
			br = new BufferedReader(new FileReader("C:/temp/test.txt"));
			while ((sCurrentLine = br.readLine()) != null) 
			{
				System.out.println(sCurrentLine);
			}
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		finally 
		{
			try
			{
				if (br != null)
					br.close();
			} 
			catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}

These types of code are very common in application code base where there is lots of IO operations.

Code inside try and catch blocks are essentially important and have some application specific logics. But what about finally block?? Most of the time, finally blocks are just copy pasted for sake of saving the resources from corruption, by closing them.

These finally blocks looks more ugly, when you have 3-4 such resources to close in single finally block. Don’t you think these finally blocks are unnecessarily there when we know, we have to close the resource anyhow without any exceptional case??

Java 7 solves this problem with try-with-resources feature.

The new fancy way with try-with-resources (syntax example)

Now look at the new way of opening and closing a resource in java 7.

public class ResourceManagementInJava7 
{
	public static void main(String[] args) 
	{
		try (BufferedReader br = new BufferedReader(new FileReader("C:/temp/test.txt")))
		{
			String sCurrentLine;
			while ((sCurrentLine = br.readLine()) != null) 
			{
				System.out.println(sCurrentLine);
			}
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
}

There are two things to closely watch:

  1. File resource (BufferedReader) is opened in try block in special manner (inside small brackets).
  2. Finally block is completely gone.

And last but not the least, code looks pretty and easy to read. It’s good ,right?? But how actually it works??

How actually it works?

In java 7, we have a new super interface java.lang.AutoCloseable. This interface have one method:

void close() throws Exception;

Java docs recommend this interface to be implemented on any resource that must be closed when it is no longer needed.

When we open any such AutoCloseable resource in special try-with-resource block, immediately after finishing the try block, JVM calls this close() method on all resources initialized in “try()” block.

For example, BufferedReader has implemented close() method file this:

public void close() throws IOException {
	synchronized (lock) {
		if (in == null)
			return;
		in.close();
		in = null;
		cb = null;
	}
}

Due to above method definition, any underlying stream or IO resource is closed when this method is invoked by JVM.

Adding functionality to custom resources

Well, this is a good resource cleanup design. But is it available to JDK native classes only?? NO. You can use it also to your custom resources.

For example, I have create a custom resource in below code:

public class CustomResource implements AutoCloseable 
{
	public void accessResource() {
		System.out.println("Accessing the resource");
	}
	
	@Override
	public void close() throws Exception {
		System.out.println("CustomResource closed automatically");
	}
}

Now I will use it in my example code:

public class TryWithCustomResource 
{
	public static void main(String[] args)
	{
		try(CustomResource cr = new CustomResource())
		{
			cr.accessResource();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

Putput in console:

Accessing the resource
CustomResource closed automatically

Output in console clearly proves that resource was closed down automatically as soon as try block was finished.

Final notes

That’s all regarding automatic resource management with try-with-resources in java 7. Let’s note down highlights point by point:

  • Before java 7, we had to use finally blocks to cleanup the resources. Finally blocks were not mandatory, but resource clean up was to prevent the system from being corrupt.
  • With java 7, no need to explicit resource cleanup. Its done automatically.
  • Automatic resource cleanup done when initializing resource in try-with-resources block (try(…) {…}).
  • Cleanup happens because of new interface AutoCloseable. Its close method is invoked by JVM as soon as try block finishes.
  • If you want to use this in custom resources, then implementing AutoCloseable interface is mandatory. otherwise program will not compile.
  • You are not supposed to call close() method in your code. This should be called automatically bu JVM. Calling it manually may cause unexpected results.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

6 thoughts on “try-with-resources in Java 7”

  1. Thanks for your post and its valuable

    try (
    BufferedReader br1 = new BufferedReader(new FileReader(“C:/temp/test1.txt”));
    BufferedReader br2 = new BufferedReader(new FileReader(“C:/temp/test2.txt”));
    BufferedReader br3 = new BufferedReader(new FileReader(“C:/temp/test3.txt”))
    )

    A request please added closing multiple resource to tutorial.

    Reply
    • Good point. In fact, we can initialize and close multiple resources as well. For example:

      public class ResourceManagementInJava7
      {
      public static void main(String[] args)
      {
      try (
      BufferedReader br1 = new BufferedReader(new FileReader(“C:/temp/test1.txt”));
      BufferedReader br2 = new BufferedReader(new FileReader(“C:/temp/test2.txt”));
      BufferedReader br3 = new BufferedReader(new FileReader(“C:/temp/test3.txt”))
      )
      {
      //Access resources
      }
      catch (IOException e)
      {
      e.printStackTrace();
      }
      }
      }

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.