Java — Try with Resources | Code Factory

Donate : Link

WordPress Blog : Link

Applications… : Link

* 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 when after the execution of that block.

* The resources declared must implement the AutoCloseable or Closeable (which extends AutoCloseable) interface.

* In try-with-resources user must have to handle Exception using catch block or using throws.

public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}
public interface AutoCloseable {
void close() throws Exception;
}
  • Simply put, to be auto-closed, a resource must be both declared and initialized inside the try, as shown below:
try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
writer.println("Hello World");
}
  • 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 — first is a typical try-catch-finally block, then the new approach, using an equivalent try-with-resources block:
package com.example.java.programming;import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* @author code.factory
*
*/
public class Test {
public static void main(String... strings) {
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 super succinct solution using try-with-resources:
package com.example.java.programming;import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* @author code.factory
*
*/
public class Test {
public static void main(String... strings) {
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
}
}
  • Multiple resources can be declared just fine in a try-with-resources block by separating them with a semicolon:
package com.example.java.programming;import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
/**
* @author code.factory
*
*/
public class Test {
public static void main(String... strings) throws FileNotFoundException {
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:
package com.example.java.programming;/**
* @author code.factory
*
*/
public class Test implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Closed resource");
}
}
  • Resources that were defined/acquired first will be closed last; let’s look at an example of this behavior:
package com.example.java.programming;/**
* @author code.factory
*
*/
public class Test {
public static void main(String... strings) throws Exception {
try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst();
AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) {
af.doSomething();
as.doSomething();
}
}
}
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");
}
}
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");
}
}

Output:

Constructor -> AutoCloseableResources_First
Constructor -> AutoCloseableResources_Second
Something -> AutoCloseableResources_First
Something -> AutoCloseableResources_Second
Closed -> AutoCloseableResources_Second
Closed -> AutoCloseableResources_First
  • A 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.
  • Before Java 9, we only could use fresh variables inside a try-with-resources block:
package com.example.java.programming;import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
/**
* @author code.factory
*
*/
public class Test {
public static void main(String... strings) throws FileNotFoundException {
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
// do something
}
}
}
  • 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) {
// do something
}
  • * 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. Therefore, we’re allowed to use the writer variable, too.