Java – Try with Resources

1. Overview

Support for try-with-resources — introduced in Java 7 — allows us to declare resources to be used in a try block with the assurance that the resources will be closed after the execution of that block.

The resources declared need to implement the AutoCloseable interface.

2. Using try-with-resources

Simply put, to be auto-closed, a resource has to be both declared and initialized inside the try:

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Hello World");
}

3. Replacing trycatch-finally With try-with-resources

The simple and obvious way to use the new try-with-resources functionality is to replace the traditional and verbose try-catch-finally block.

Let’s compare the following code samples.

The first is a typical try-catch-finally block:

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

And here’s the new super succinct solution using try-with-resources:

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

Here’s where to further explore the Scanner class.

4. try-with-resources With Multiple Resources

We can declare multiple resources just fine in a try-with-resources block by separating them with a semicolon:

try (Scanner scanner = new Scanner(new File("testRead.txt"));
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
    while (scanner.hasNext()) {
	writer.print(scanner.nextLine());
    }
}

5. A Custom Resource With AutoCloseable

To construct a custom resource that will be correctly handled by a try-with-resources block, the class should implement the Closeable or AutoCloseable interfaces and override the close method:

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

6. Resource Closing Order

Resources that were defined/acquired first will be closed last. Let’s look at an example of this behavior:

Resource 1:

public class AutoCloseableResourcesFirst implements AutoCloseable {

    public AutoCloseableResourcesFirst() {
        System.out.println("Constructor -> AutoCloseableResources_First");
    }

    public void doSomething() {
        System.out.println("Something -> AutoCloseableResources_First");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_First");
    }
}

Resource 2:

public class AutoCloseableResourcesSecond implements AutoCloseable {

    public AutoCloseableResourcesSecond() {
        System.out.println("Constructor -> AutoCloseableResources_Second");
    }

    public void doSomething() {
        System.out.println("Something -> AutoCloseableResources_Second");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_Second");
    }
}

Code:

private void orderOfClosingResources() throws Exception {
    try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst();
        AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) {

        af.doSomething();
        as.doSomething();
    }
}

Output:

Constructor -> AutoCloseableResources_First
Constructor -> AutoCloseableResources_Second
Something -> AutoCloseableResources_First
Something -> AutoCloseableResources_Second
Closed AutoCloseableResources_Second
Closed AutoCloseableResources_First

7. catch and finally

try-with-resources block can still have the catch and finally blocks, which will work in the same way as with a traditional try block.

8. Java 9 – Effectively FinalVariables

Before Java 9, we could only use fresh variables inside a try-with-resources block:

try (Scanner scanner = new Scanner(new File("testRead.txt")); 
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { 
    // omitted
}

As shown above, this was especially verbose when declaring multiple resources. As of Java 9 and as part of JEP 213, we can now use final or even effectively final variables inside a try-with-resources block:

final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) { 
    // omitted
}

Put simply, a variable is effectively final if it doesn’t change after the first assignment, even though it’s not explicitly marked as final.

As shown above, the scanner variable is declared final explicitly, so we can use it with the try-with-resources block. Although the writer variable is not explicitly final, it doesn’t change after the first assignment. So, we can to use the writer variable too.

9. Conclusion

In this article, we discussed how to use try-with-resources and how to replace trycatch, and finally with try-with-resources.

We also looked at building custom resources with AutoCloseable and the order in which resources are closed.

The complete source code for the example is available in this GitHub project.

Related posts:

Java Program to Perform the Sorting Using Counting Sort
Java – Delete a File
Xử lý ngoại lệ trong Java (Exception Handling)
How to Replace Many if Statements in Java
Deploy a Spring Boot WAR into a Tomcat Server
Java Program to Perform Encoding of a Message Using Matrix Multiplication
The Spring @Controller and @RestController Annotations
Java Program to Solve Knapsack Problem Using Dynamic Programming
Biến trong java
Java Program to Implement Shoelace Algorithm
Java Program to Implement ArrayBlockingQueue API
Getting Started with GraphQL and Spring Boot
Reading an HTTP Response Body as a String in Java
Các kiểu dữ liệu trong java
Java Program to Implement Quick Sort with Given Complexity Constraint
Java Program to find the number of occurrences of a given number using Binary Search approach
Java Program to Compute Discrete Fourier Transform Using the Fast Fourier Transform Approach
Guava CharMatcher
Java Program to Search for an Element in a Binary Search Tree
Java Program to Find All Pairs Shortest Path
A Guide to the Java LinkedList
Java Program to Implement Park-Miller Random Number Generation Algorithm
Spring Security OAuth2 – Simple Token Revocation
Java Program to Implement VList
Java Program to Describe the Representation of Graph using Adjacency Matrix
Setting a Request Timeout for a Spring REST API
Java – Byte Array to Reader
Các chương trình minh họa sử dụng Cấu trúc điều khiển trong Java
Handling Errors in Spring WebFlux
Một số ký tự đặc biệt trong Java
Spring Boot Configuration with Jasypt
Hướng dẫn sử dụng Printing Service trong Java