Main Tutorials

Java try-with-resources example

This article shows you how to use try-with-resources in Java.

Table of contents:

1 Java try-with-resources before and after

Review a Java file copy example. Before Java 7, we manually used the try-finally block to ensure that resources were closed.


    public static void copyFilePlainJava(String from, String to)
        throws IOException {

        InputStream inStream = null;
        OutputStream outStream = null;

        try {

            inStream = new FileInputStream(new File(from));
            outStream = new FileOutputStream(new File(to));

            byte[] buffer = new byte[1024];

            // if this throws exception
            int length;
            while ((length = inStream.read(buffer)) > 0) {
                outStream.write(buffer, 0, length);
                outStream.flush();
            }

        } finally {
            // if this throws exception
            if (inStream != null)
                inStream.close();

            // this has a leak
            if (outStream != null)
                outStream.close();
        }

    }

However, this example might have a resource leak; if the while copy bytes process throws an exception, and the inStream.close() throws an exception, then the outStream has a resource leak and causes a performance issue. We can solve this by wrapping the close stream with another layer of try-catch, but it’s too lengthy and error-prone.

In Java 7, we can use try-with-resources to ensure resources after the try block are automatically closed. And any exceptions thrown from the try-with-resources statement will be suppressed. Review the below try-with-resources example.


  public static void copyFilePlainJava(String from, String to) throws IOException {

      // try-with-resources
      try (InputStream inStream = new FileInputStream(new File(from));
           OutputStream outStream = new FileOutputStream(new File(to))) {

          byte[] buffer = new byte[1024];

          int length;
          while ((length = inStream.read(buffer)) > 0) {
              outStream.write(buffer, 0, length);
              outStream.flush();
          }

      }

  }

The try-with-resources is clean, with less code and fewer bugs, and the resources automatically close after the try block.

2. try-with-resources with single resource

Below is a classic old Java BufferedReader to open and read a file and print it out line by line.


package com.mkyong;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TestApp {

  public static void main(String[] args) {

      BufferedReader br = null;
      String line;

      try {

          br = new BufferedReader(new FileReader("c:\\testing.txt"));
          while ((line = br.readLine()) != null) {
              System.out.println(line);
          }

      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          try {
              if (br != null) br.close();
          } catch (IOException ex) {
              ex.printStackTrace();
          }
      }


  }
}

In Java 7 and above, we rewrite the above classic BufferedReader code with the try-with-resources like below:


package com.mkyong.java18;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TestApp {

    public static void main(String[] args) {

        String line;

        try (BufferedReader br = new BufferedReader(
                new FileReader("c:\\testing.txt"))) {

            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

3. try-with-resources with multiple resources

We can use the semicolon : to declare multiple resources in a try-with-resources block. The multiple resources are automatically closed after the try block.


  // try-with-resources
  try (InputStream inStream = new FileInputStream(new File(from));
       OutputStream outStream = new FileOutputStream(new File(to))) {

      byte[] buffer = new byte[1024];

      int length;
      while ((length = inStream.read(buffer)) > 0) {
          outStream.write(buffer, 0, length);
          outStream.flush();
      }

  }

Yet another example.


  try (FileReader fr = new FileReader(path);
       BufferedReader br = new BufferedReader(fr)) {
      return br.readLine();
  }

3.1 JDBC example.

Below is a classic JDBC example open and closing resources to update a row.


   Connection connection = null;
   PreparedStatement ps = null;

   try {
       connection = dataSource.getConnection();
       ps = connection.prepareStatement(SQL_UPDATE_POST);

       ps.setInt(1, postId);

       ps.executeUpdate();

   } catch (Exception e) {
       //
   } finally {

       if (ps != null) {
           ps.close();
       }

       if (connection != null) {
           connection.close();
       }
   }

In Java 7, we can rewrite the code with the try-with-resources block.


  try (Connection connection = dataSource.getConnection();
       PreparedStatement ps = connection.prepareStatement(SQL_UPDATE_POST)) {
      ps.setInt(1, postId);

      ps.executeUpdate()

  } catch (Exception e) {
      //...
  }

4. Custom resource with AutoCloseable interface

We can implement the AutoCloseable interface to create a custom resource that will be handled by the try-with-resources block.

MyFileResource.java

package com.mkyong.io;

public class MyFileResource implements AutoCloseable {

  public MyFileResource() {
    // constructor
  }

  @Override
  public void close() throws Exception {
      // implements the logic to close the resource here
      System.out.println("MyFileResource closed");
  }

}

  try (MyFileResource file = new MyFileResource()) {
      // some logic
  } catch (Exception e) {
      throw new RuntimeException(e);
  }

5. Resource open and closing order

In try-with-resources, the resource that declares first will be closed last.

MyFileResourceA.java

package com.mkyong.io;

public class MyFileResourceA implements AutoCloseable {

  public MyFileResourceA() {
      System.out.println("MyFileResourceA");
  }

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

}
MyFileResourceZ.java

package com.mkyong.io;

public class MyFileResourceZ implements AutoCloseable {

  public MyFileResourceZ() {
      System.out.println("MyFileResourceZ");
  }

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

}

Run it.


  try (MyFileResourceA fileA = new MyFileResourceA();
       MyFileResourceZ fileZ = new MyFileResourceZ()) {

  } catch (Exception e) {
      throw new RuntimeException(e);
  }

Output

Terminal

MyFileResourceA
MyFileResourceZ
MyFileResourceZ closed
MyFileResourceA closed

Let’s reverse the resource sequence and review the output again.


  try (MyFileResourceA fileZ = new MyFileResourceZ();
       MyFileResourceZ fileA = new MyFileResourceA()) {

  } catch (Exception e) {
      throw new RuntimeException(e);
  }

Output

Terminal

MyFileResourceZ
MyFileResourceA
MyFileResourceA closed
MyFileResourceZ closed

6. Java 9 – final or effectively final variables

Before Java 9, we must declare a new variable for each resource.


  try (InputStream inStream = new FileInputStream(new File(from));
       OutputStream outStream = new FileOutputStream(new File(to))) {

      //...

  }

Java 9, JEP 213 allow final or effectively final variables to be used as resources in try-with-resources statement.


  InputStream inStream = new FileInputStream(from);   // effectively final
  OutputStream outStream = new FileOutputStream(to);  // effectively final

  try (inStream; outStream) {
    //...
  }

What is effectively final variable?
In Java, Any variable that is assigned once and only once, is effectively final.

The below code will cause the compile-time error because the outStream is changed after it is initialized.


  InputStream inStream = new FileInputStream(from);   // effectively final
  OutputStream outStream = new FileOutputStream(to);
  outStream = new FileOutputStream(to); // change again, not effective final

  try (inStream; outStream) { // compile-time error
    //...
  }

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-io

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
10 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
infoj
8 years ago

Sorry to say but this post is not as detailed as it should be. Please have a look at this post for more detailed explanation.

try-with-resources

Rodrigo Feio Dias
5 years ago

try-with-resources provides clean code experience

Vijay Raj
7 years ago

What if we have multiple resources to close.

UmeshAwasthi
6 years ago
Reply to  Vijay Raj

you can open multiple resource in try statement

try (BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
Scanner scanner = new Scanner(new File(fileName1))) {}

Andrii Polunin
7 years ago

Good and succinct comparison between two approaches. However resources should not be chained in try-with-resources statement like this new BufferedReader(new FileReader(“C:\testing.txt”)). Generally it might lead to a situation when inner resource will not be closed. Take a look here for more details: http://www.softwaregeek.net/2014/01/java-7-try-with-resources-statement.html

infoj
8 years ago

try-with-resources and multi catch statement in Java 7 help to reduce boiler plate code in Java exception handling.

cody banks
8 years ago

Thats a good comparison between the two approaches. If you are interested to see how the generated byte-code looks like you can check out – https://blog.srcclr.com/exception-handling-with-try-with-resources-statement-in-java-7/

najeh
10 years ago

exemple de mode non connect? en vb avec sql server svp

Pankaj
11 years ago

Hi,

I always liked your article but I think you missed to explain the difference incase of exception handling here. I have written a blog post explaining it in detail. Please have a look.

http://www.journaldev.com/592/try-with-resource-example-java-7-feature-for-automatic-resource-management