Core Java

Java Try with Resources Example

1. Introduction

Try-with-resources in Java 7 is a new exception handling mechanism that makes it easier to correctly close resources that are used within a try-catch block.

2. Whats covered in this blog post?

  • Resource Management With Try-Catch-Finally, Old School Style
  • Managing resources that need to be explicitly closed is somewhat tedious before Java 7.

printFile() method

private static void printFile() throws Exception{
        FileInputStream input = null;
        try {
            input = new FileInputStream("file.txt");
            int data = input.read();
            while (data != -1) {
                System.out.print((char) data);
                data = input.read();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            input.close();
        }
    }

The code marked in bold is where the code can throw an Exception. As you can see, that can happen in 3 places inside the try-block, and 1 place inside the finally-block. The finally block is always executed no matter if an exception is thrown from the try block or not. That means, that the InputStream is closed no matter what happens in the try block. Or, attempted closed that is. The InputStream's close() method may throw an exception too, if closing it fails.

Imagine that an exception is thrown from inside the try block. Then the finally block is executed. Imagine then, that an exception is also thrown from the finally block. Which exception do you think is propagated up the call stack?

The exception thrown from the finally block would be propagated up the call stack, even if the exception thrown from the try block would probably be more relevant to propagate.

3. Java Try with Resources

In Java 7 you can write the code from the example above using the try-with-resource construct like this:

printFileJava7() method

private static void printFileJava7() throws IOException {
	    try(FileInputStream input = new FileInputStream("file.txt")) {
	        int data = input.read();
	        while(data != -1){
	            System.out.print((char) data);
	            data = input.read();
	        }
	    }
	}

Notice the first line inside the method:

try(FileInputStream input = new FileInputStream("file.txt"))

This is the try-with-resources construct. The FileInputStream variable is declared inside the parentheses after the try keyword. Additionally, a FileInputStream is instantiated and assigned to the variable.

When the try block finishes the FileInputStream will be closed automatically. This is possible because FileInputStream implements the Java interface java.lang.AutoCloseable. All classes implementing this interface can be used inside the try-with-resources construct.

If an exception is thrown both from inside the try-with-resources block, and when the FileInputStream is closed (when close() is called), the exception thrown inside the try block is thrown to the outside world. The exception thrown when the FileInputStream was closed is suppressed. This is opposite of what happens in the example first in this text, using the old style exception handling (closing the resources in the finally block).

4. Try with Resources with finally

We can use finally block along with try with resources. In this section, we will see how the program will behave when both of these are present. Below is the sample code,

package com.jcg.autoclose;

/**
 * @author Santosh Balgar Sachchidananda
 * TryWithResourcesAndFinallyBlock demonstrates how an AutoCloseable resource works when there is a finally block
 */

public class TryWithResourcesAndFinallyBlock {
    public static void main(String[] args) {
        try (MyCustomAutoCloseable myCustomAutoCloseable = new MyCustomAutoCloseable()) {
            System.out.println("****** Executing try block ******");
            myCustomAutoCloseable.printHello();
        } catch (Exception ex) {
            System.out.println("****** Executing catch block ******");
        } finally {
            System.out.println("****** Executing finally block ******");
        }
    }
}

/**
 * MyCustomeAutoCloseable is an Auto Closeable resource that implements AutoCloseable interface
 */

class MyCustomAutoCloseable implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println("******* MyCustomAutoCloseable close() method *******");
    }

    public void printHello() {
        System.out.println("******* Hello!! I am MyCustomAutoCloseable, an AutoCloseable resource *******");
    }

}

The output of the program is as follows,

Java try with Resources - TryWithResourcesAndFinallyBlock output
TryWithResourcesAndFinallyBlock output

Finally block is executed at the last. Resources are closed before executing finally block. If both try and finally block throw an exception, then exception thrown from the finally block will be suppressed.

5. Try with resources vs Try with finally

Try with resources always makes sure the resources are closed reliably.

Try catch finally sequence sometimes may result in something called exception masking. That means when the code in try block throws some exception and code in finally block also throws an exception while closing the resource then, the caller sees the exception thrown by the finally block. even though, the exception thrown by a try block is more relevant. The exception thrown from try block gets masked by the exception thrown by finally block.

Try with resource block prevents the exception masking. It ensures always correct exception is thrown. If both try block and close method throw an exception, then the exception thrown in the try block is returned.

Try with resources should be used instead of try-catch-finally wherever possible. It is very common to forget to call the close method after hours of coding and it leads to serious issues in the application like Out of Memory. The code is much shorter, easier to read and maintain.

6. Using Multiple Resources

You can use multiple resources inside a try-with-resources block and have them all automatically closed. Here is an example:

printFileJava7MultiResources() method

private static void printFileJava7MultiResources() throws IOException {
        try (FileInputStream input = new FileInputStream("file.txt");
             BufferedInputStream bufferedInput = new BufferedInputStream(input)) {
            int data = bufferedInput.read();
            while (data != -1) {
                System.out.print((char) data);
                data = bufferedInput.read();
            }
        }
    }

This example creates two resources inside the parentheses after the try keyword. An FileInputStream and a BufferedInputStream. Both of these resources will be closed automatically when execution leaves the try block.

The resources will be closed in reverse order of the order in which they are created / listed inside the parentheses. First the BufferedInputStream will be closed, then the FileInputStream.

7. Custom AutoClosable Implementation

The try-with-resources construct does not just work with Java’s built-in classes. You can also implement the java.lang.AutoCloseable interface in your own classes, and use them with the try-with-resources construct.

The AutoClosable interface only has a single method called close(). Here is how the interface looks:

AutoClosable.java

1
2
3
4
public interface AutoClosable {
 
    public void close() throws Exception;
}

Any class that implements this interface can be used with the try-with-resources construct. Here is a simple example implementation:

MyAutoClosable.java

01
02
03
04
05
06
07
08
09
10
11
public class MyAutoClosable implements AutoCloseable {
 
    public void doIt() {
        System.out.println("MyAutoClosable doing it!");
    }
 
    @Override
    public void close() throws Exception {
        System.out.println("MyAutoClosable closed!");
    }
}

The doIt() method is not part of the AutoCloseable interface. It is there because we want to be able to do something more than just closing the object.

Here is an example of how the MyAutoClosable is used with the try-with-resources construct:

myAutoClosable() method

1
2
3
4
5
6
private static void myAutoClosable() throws Exception {
 
    try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
        myAutoClosable.doIt();
    }
}

8. Resources order of closing

In this section, I am demonstrating the order of closing when multiple resources are used with a try block. Resources are closed in the reverse order of creation or reverse order of how they are listed in the parenthesis.

I have created two auto closeable classes MyFirstAutoCloseable and MySecondAutoCloseable. The demo program is as below,

package com.jcg.autoclose;

/**
 * @author Santosh Balgar Sachchidananda
 * This is a demo class showing the try with multiple resources and their order of closing
 */
public class TryWithMultipleResourcesDemo {
    public static void main(String[] args) {
        System.out.println("##### Try with multiple resources demo ####");
        try(MyFirstAutoCloseable mfa = new MyFirstAutoCloseable(); MySecondAutoCloseable msa = new MySecondAutoCloseable()) {
            System.out.println("Inside try block");
            mfa.printHello();
            msa.printHello();
        } catch(Exception ex) {
            System.out.println("Inside catch block");
        }
    }
}

/**
 * MySecondAutoCloseable is an example of AutoCloseable resource
 * All classes implementing AutoCloseable should provide a definition for close method
 */

class MySecondAutoCloseable implements AutoCloseable{
    @Override
    public void close() throws Exception {
        System.out.println("******* MySecondAutoCloseable close() method *******");
    }

    public void printHello() {
        System.out.println("******* Hello!! I am MySecondAutoCloseable, an AutoCloseable resource *******");
    }
}

/**
 * MyFirstAutoCloseable is an example of AutoCloseable resource.
 * All classes implementing AutoCloseable should provide a definition for close method
 */

class MyFirstAutoCloseable implements AutoCloseable{
    @Override
    public void close() throws Exception {
        System.out.println("######## MyFirstAutoCloseable close() method ########");
    }

    public void printHello() {
        System.out.println("######## Hello!! I am MyFirstAutoCloseable, an AutoCloseable resource ########");
    }
}

close() method of MySecondAutoCloseable is called first while closing the resources. This can be seen in the below output screenshot,

Java try with Resources - TryWithMultipleResources output
TryWithMultipleResources output

9. Download the InelliJ Idea Project

This was an example of how try-with-resources statement in Java 7.

Download
You can download the full source code of this example here: Java Try with Resources Example

Last updated on Oct. 09, 2019

Alvin Reyes

Alvin has an Information Technology Degree from Mapua Institute of Technology. During his studies, he was already heavily involved in a number of small to large projects where he primarily contributes by doing programming, analysis design. After graduating, he continued to do side projects on Mobile, Desktop and Web Applications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button