Close the resources in finally block is a well know rule for all java developers. As part of exception handling mechanism, we should always ensure to close and release the resources that is used inside the block. In a block of code which is enclosed in a try-catch block, if an exception is thrown the normal flow is altered.

Look at the above code block. The best place to close and release all the resources is finally block. So what is the resource we are talking about here? Resources means database connection, file connections, etc.

Poor Structure

As stated above, we are going to close the resources in the finally block. Look at the following code, how ugly it looks like.

Automatic Resource Management (ARM)

In Java 7, we got a nice feature to manage these resources automatically. Manage is really a hype word here, all it does is close the resources. Automatic resource management, helps to close the resources automatically.

Resource instantiation should be done within try(). A parenthesis () is introduced after try statement and the resource instantiation should happen within that paranthesis as below,

try-with-resources and AutoCloseable

All the classes cannot be used in try-with-resources. AutoCloseable is an interface used as a contract to implement try-with-resources. Classes that implements AutoCloseable must be used as a resource in try-with-resources, else we will get compilation error.

close is the only method in AutoCloseable and it gets automatically invoked at runtime.

Multiple classes can be declared within the same try as “try (Lion lion = new Lion(); Tiger tiger = new Tiger()) {…”

During initialization of multiple resources in ‘try’, if there is any issue then immediately in the reverse order those resources that are already initialized will be closed.

When multiple classes are used in ‘try’, then the close method is called in the reverse order. To understand this, check the below example.

try-with-resources, can have catch and finally. They work as usual and no change in it.

In try-with-resources on exception, before going to catch the close statements will be executed.

While implementing AutoCloseable, best practice is to throw specific exception and not the highest level ‘Exception’ itself. This needs to highlighted because the signature of ‘close’ in AutoCloseable throws Exception.

On implementation, AutoCloseable.close should not throw InterrupedException, because at runtime if this exception is suppressed it will cause issues in thread handling.

By specification this close method is not required to be idempotent. But still, it is best practice to implement it as idempotent. That is, even if the close method is invoked multiple times, it should act as same.

Closeable is an interface that extends AutoCloseable and its close method must be idempotent.

Resource declared in try gets instantiated just before the start of the try-block.

Resource is implicitly declared as final.

Custom Implementation of AutoCloseable

Let us create a custom class that implement AutoCloseable. It is not rocket science, there is only one method named ‘close’ in the interface and implementing that is sufficient.

Lion.java

package com.javapapers.exceptionhandling;
public class Lion implements AutoCloseable {
public Lion() {
System.out.println("LION is OPEN in the wild.");
};
public void hunt() throws Exception {
throw new Exception("DeerNotFound says Lion!");
}
public void close() throws Exception {
System.out.println("LION is CLOSED in the cage.");
throw new Exception("Unable to close the cage!");
}
}

Output for above example:

Look at the sequence of output listed above to understand the flow of control and the order in which the close method is invoked internally.

Throwable.getSuppressed Exceptions

Read the Lion and Tiger example line by line. There is an important point to understand is hidden in it. Now go back and read Lion.java

public void close() throws Exception {
System.out.println("LION is CLOSED in the cage.");
throw new Exception("Unable to close the cage!");
}

Lion’s close throws an exception, but where is it in the output? It got suppressed. That is the concept of try-with-resources.

If an exception is thrown in the try block, then the control will be transferred to catch. In between the jump to catch block the close() will be internally invoked for the registered resources.

Inside the close(), there is a possibility for an exception while closing the resource. If an exception is thrown (as given in Lion example), then it will be suppressed and the exception that is thrown in the try block (before calling close), will be exposed.

So how do we know about the suppressed exception? Here you go, use the Throwable.getSuppressed get the exceptions that are suppressed in try-with-resources.

If there are multiple resources to be closed and an exception is thrown during closing of one exception, irrespective of that all the resources will be closed.

When try-with-resources compiled to bytecode…

As given in Java Language Specification,

try (VariableModifiersopt R Identifier = Expression ...)
Block

following is the equivalent code of above, when converted to without try-with-resources,