Java – Try with Resources | Code Factory


Donate : Link

Medium 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;
}

Using try-with-resources

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

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

try-with-resources With Multiple Resources

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

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:
package com.example.java.programming;

/**
 * @author code.factory
 *
 */
public class Test implements AutoCloseable {

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

}

Resource Closing Order

  • 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

catch & finally

  • 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.

Java 9: Effectively Final Variables

  • 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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s