Java provides a feature to make the code more robust and to cut down the lines of code. This feature is known as Automatic Resource Management(ARM) using try-with-resources from Java 7 onwards. This approach used to cause memory leaks and performance hit when we forgot to close the resource. The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed once your program is done using it. For example, a File resource or JDBCresource for a database connection or a Socket connection resource.

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

Scanner scanner = null;

// Using conventional approach
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();
    }
}

// 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();
}

 

Before Java 9 a resource that is to be automatically closed must be created inside the parentheses of the try block of a try-with-resources construct. From Java 9, this is no longer necessary. If the variable referencing the resource is effectively final, you can simply enter a reference to the variable inside the try block parentheses. Here is an example of the Java 9 try-with-resources enhancement:

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

try(input) {
  while (input.hasNext()) {
      System.out.println(input.nextLine());
  }
}

 

Multiple resources can be declared just fine in a try-with-resources block by separating them with semicolon. Resources that were defined/acquired first will be closed last.

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

 

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");
  }
}