Java Try-with-Resource (autoclosable) Tutorial

In this section, we will learn what the `try-with-resource` is and how it works in Java.

What is try-with-resources in Java?

In a program, when we want to communicate with an external resource, we are first required to establish a connection with that resource and when we’re done, usually we should close the connection as well.

The traditional way before Java 8 was to use the `finally` block to make sure the instructions for closing connection will be executed, whether or not an exception occurred in a program.

Exception handling in Java without autoclosable example:

public class Simple {

    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        try{
            fileInputStream = new FileInputStream("file-directory");
        }catch (IOException exception){
            System.out.println(exception.getMessage());
        }finally {
            if (fileInputStream !=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
}

Note: `FileInputStream` class is used to create objects that can be used to make a connection to a file and read/write its content.

Also note that any variable declaration inside a `try` block is considered local and block scope, so it’s not accessible outside of that block.

So we first created a variable of type `FileInputStream` outside of the `try` block and set value `null` for it. This means the variable is referenced to nothing.

Next, inside the `try` block, we create a new object of type `FileInputStream` and store the memory address of this object into the variable.

If the object is created successfully, then reference of the object is stored in the variable otherwise the variable still has the `null` value.

Now in the `finally` block, we first checked to see if the value of the variable is still `null` or it refers to the object that was created via `FileInputStream` class.

If there was an object, then we call the `close()` method of this object in the `finally` block to close the connection to the external file that this object has the connection with.

Calling the `close()` method itself can throw an exception of type `IOException` class. So we’re also required to surround the call to the `close()` method, in a try/catch block and catch the exception if it occurred!

That’s the traditional way of closing a connection via external resource (file).

As you can see, there’re many boilerplates just for one simple call to the `close()` method!

Since the Java 8 the autoclosable was introduced and via autoclosable, we can declare an object in the `try` block and it will be automatically closed after the execution of the block’s instructions is done.

How to declare try-with-resources in Java? (Try-with-Resources syntax)

try(autoclosable-resource){

/*...*/

}catch(parameter){/*...*/}

To use autoclosable, we put a pair of parentheses after the `try` keyword and declare the objects that connect to external resources.

Note: the classes that we used to create objects from should’ve also implemented the `AutoCloseable` interface.

For example, the `FileInputStream` class implemented this interface and so we can use it in the auto-closeable.

Example: using try-with-resources in Java

public class Simple {

    public static void main(String[] args) {
        
        try(FileInputStream fileInputStream = new FileInputStream("file-directory")){
            fileInputStream.read();
        }catch (IOException exception){
            System.out.println(exception.getMessage());
        }
    }
}

As you can see, we didn’t use the `finally` block and call the `close()` method in that block anymore! This process is done automatically behind the scene now.

Using Try-with-Resources with multiple resources in Java

In the parentheses of the `try` block, we can create as many objects as needed in the block. In such case all the classes that we create objects from should’ve implemented the `AutoClosable` interface.

We use semicolon `;` to separate objects from each other in the parentheses. Also, we don’t put `;` for the last object.

Example: Java Try-with-Resources with multiple resources

public class Simple {

    public static void main(String[] args) {
        AutoCloseable autoCloseable = ()-> System.out.println("Good bye!");
        try(autoCloseable; FileInputStream fileInputStream = new FileInputStream("file-directory")){
            fileInputStream.read();
        }catch (IOException exception){
            System.out.println(exception.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output:

Good bye!

file-directory (The system cannot find the file specified)

 

Remember: as explained in the lambda section, in places where a reference to a functional interface is needed, we can use either an object from a class that implemented that functional interface or a lambda expression.

In this example, because the `AutoClosable` is in fact a functional interface, we used a lambda expression to create an instance from this interface.

As you can see, after the `try` block is executed, the call to the `close()` method of the ` autoCloseable` occurred automatically and we saw the message `Good bye!` in the output stream as well.

Java AutoClosable interface and creating a custom Resource

The `AutoClosable` interface is a functional one, and it has an abstract method named `close()` that will be called by the runtime engine after the `try` block is finished. This means we can also create a class and implement this interface and use it in the parentheses of the `try` block!

Example: creating custom resource with Java AutoClosable interface

package com.example.demo;

public class Main implements AutoCloseable{

    public static void main(String[] args) {
        try (Main main = new Main()){
            main.sayHi();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
    public void sayHi(){
        System.out.println("Hi:)");
    }
    @Override
    public void close() throws Exception {
        System.out.println("The Main class is an autoclosable interface! \nGood bye!");
    }
}

 

Facebook
Twitter
Pinterest
LinkedIn

Top Technologies