Java 7 – try-with-resources with examples

In this article, we will discuss new feature called try-with-resources statement introduced in Java 1.7 version as part of Exception handling for automatic resource management i.e.; ARM

1. Until Java 1.6 version:

Whenever we are dealing with any type of resources then it must be closed explicitly, otherwise all these limited resources remain opened and thereby not allowing other users to use & wait time increases to perform required operation

The type of resources can be,

  • File resource
  • Stream resource
  • Database connection resource
  • Network resource
  • Socket connection resource
  • Any I/O resources
  • Scanner resource
  • etc

So, programmer dealing with these types of resources must close it explicitly. To do so, programmer can take advantage of try-catch-finally blocks to close resources after necessary null-safety checking inside finally-block

1.1 Pseudo code for try-catch-finally block:

try {

	// open and use resources here
}
catch(Throwable t) {

	// exception handling code for any exception raised from try block
}
finally {

	// finally block always gets executed - code clean-up activities
	// close resources, opened in the try block after null-safety checking
}

Let us see an example involving file resource

ResourcesClosingUsingTryCatchFinallyBlock.java

package in.bench.resources.exception.handling;

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

public class ResourcesClosingUsingTryCatchFinallyBlock {

	public static void main(String[] args) {

		// local variable
		BufferedReader bufferedReader = null;

		// try-catch-finally block sequence
		try {

			// open file resource
			bufferedReader = new BufferedReader(
					new FileReader("D:\\Bench\\test.txt"));

			// use file resource for further processing
			System.out.println(bufferedReader.readLine());
		}
		catch (IOException ioex) {

			// exception handling - here just printing stack trace
			ioex.printStackTrace();
		}
		finally {

			// close file resources, after null checking
			try {
				if (bufferedReader != null)
					bufferedReader.close();
			}
			catch (IOException ioex) {
				ioex.printStackTrace();
			}
		}
	}
}

1.2 Shortcomings of above program with try-catch-finally block sequence:

  • Programmer has to close opened resources explicitly inside finally-block
  • Also before closing file resources inside finally-block, it need to be checked against null. Otherwise, null pointer exception raised when close() is invoked against null reference
  • Mandatorily writing finally-block to close resources after null checking increases the size of the program (i.e.; length of the code increases)
  • Which increases the complexity and reducing readability of the program
  • Note: whenever try-block raises exception and finally-block executes, then there is a possibility of raising exception from finally-block In this case, exception from finally-block will be thrown overriding the exception from try-block

2. try-with-resources – ARM

  • To overcome above shortcoming using try-catch-finally block sequence
  • Sun people (now Oracle group) introduced new feature called try-with-resources statement in Java 1.7 version
  • Reason : for automatic resource management i.e.; ARM

2.1 Java 1.7 version onwards:

  • Using try-with-resources statement, programmer doesn’t need to explicitly close opened resources
  • Rather it will be automatically closed once control reachesend of try-catch block

Pseudo code for try-with-resources statement:

try(// open resources inside try argument) {

		// use resources here
	}
	catch(Throwable t) {

		// exception handling code for any exception raised from try block
	}
	// opened resources inside try block are auto-closed,
	// as soon as control reaches to end of try-catch block execution

2.2 Example on try-with-resources – ARM

  • Let us re-write same example using try-with-resources statement
  • involving some file-resources

AutomaticResourcesMgmtUsingTryWithResourcesInJava7.java

package in.bench.resources.exception.handling;

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

public class AutomaticResourcesMgmtUsingTryWithResourcesInJava7 {

	public static void main(String[] args) {

		// open file resource using try-with-resources statement
		try (BufferedReader br = new BufferedReader(
				new FileReader("D:\\Bench\\test.txt"))) {

			// use file resource for further processing
			System.out.println(br.readLine());
		}
		catch (IOException ioex) {

			// exception handling - here just printing stack trace
			ioex.printStackTrace();
		}
	}
}

2.3 Advantages of using try-with-resources statement:

  • All opened resources inside try argument will be auto-closed once control reaches to end of try-catch block execution
  • Irrespective of whether program terminates normally or abnormally, all opened resources will be auto-closed
  • By looking at both versions (Java 1.6 & Java 1.7) of the code, it is seen that later version has lesser lines of code compared with former version
  • That’s length of the program is very much less since there is no need to write finally-block for explicit resources closing statement after necessary null-safety checking
  • Which is taken care by new advanced feature called try-with-resources statement introduced Java 1.7 version
  • Hence, complexity of the program decreases and readability improves

2.4 Rules for using try-with-resources statement:

  1. All resources declared as part of try-with-resources statement must be AutoCloseable (i.e.; all resources must implements java.lang.AutoCloseable interface)
  2. Multiple resources can be declared inside try-block argument; but they are all must be separated by semi-colon (;)
  3. While using try-with-resources statement, try block itself is enough. There is no compulsion to write/code either catch-block or finally-block followingtry-block, whereas in prior versions try-block must be followed by either catch-block or finally-block
  4. All resource reference variable declared inside try block argument are implicitly final. Therefore, resource reference variable can’t changed or re-assigned within try block

Let us discuss each case individually with examples for detail understanding

Rule 1: All resources must be Auto Closeable

  • All resources must be AutoCloseable i.e.; resources declared as part of try-with-resources statement should extend java.lang.AutoCloseable interface
  • java.lang.AutoCloseable interface is introduced in Java 1.7 version and it contains only one method called close();
  • Method signature:
public void close() throws IOException;
  • Example: all I/O related resources, database resources, network resources implements java.lang.AutoCloseable interface
  • Some of the resources which implements java.lang.AutoCloseable interface are;
    1. FileWriter & FileReader classes
    2. BufferedWriter & BufferedReader classes
    3. Statement, PreparedStatement, CallableStatement interface
    4. FileInputStream & FileOutputStream classes
    5. PrintStream class
  • AutoCloseable.java (from java.lang package)
  • Closeable.java (java.io.Closeable extends java.lang.AutoCloseable interface)

Rule 2: Multiple resources can be declared with semi-colon (;) separating them

  • Declaring multiple resources within single try-with-resources is very much possible
  • But all resources must be separated with semi-colon (;)
  • Example: assume we want to open two resources; one for reading file contents & other for writing content
  • Syntax:
try (Resource1; Resource2; Resource3) { 

          // use resources here 

}
  • Let us write/code one example involving 2 resources

ReadAndWriteUsingTryWithResourcesStatement.java

package in.bench.resources.exception.handling;

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

public class ReadAndWriteUsingTryWithResourcesStatement {

	public static void main(String[] args) {

		// open file resource using try-with-resources statement
		try (BufferedReader br = new BufferedReader(
				new FileReader("D:\\Bench\\Read\\test1.txt"));
				BufferedWriter bw = new BufferedWriter(
						new FileWriter(
								"D:\\Bench\\Write\\test2.txt"))) {

			// use file resource for further processing
			String str;

			// read file contents from 1st resource i.e.; BR/FR
			// write file contents into 2nd resources using BW/FW
			while ((str = br.readLine()) != null) {
				bw.write(str);
			}
		}
		catch (IOException ioex) {

			// exception handling - here just printing stack trace
			ioex.printStackTrace();
		}
	}
}

Explanation:

In the above example,

  • There are 2 resources i.e.;
  • one resource for reading file contents from specified location in the FileReader resource
  • And other resource is for file writing using FileWriter resource
  • Inside try-block, we are reading line-by-line contents of file from BufferedReader & writing to another resource using BufferedWriter
  • It is very simple, as it doesn’t involve anywhere to close resources explicitly
  • In fact, there is no finally-block where we generally write close resources after necessary null-safety checking, prior to Java 1.7 version
  • Note: there is no compulsion to put catch-block too, we will see this rule as well in the subsequent case

Rule 3: New try-with-resources statement can work alone i.e.; there is no need to write either catch-block or finally-block following the try-block

  • Until Java 1.6 version, try-block must be followed by either catch-block or finally-block or else it should have try-catch-finally block sequence
  • But with introduction of new feature called try-with-resources statement for exception handling in Java 1.7 version, there is no compulsion like catch-block or finally-block should follow try-block
  • Rather try-block alone work without raising any compile-time error
  • Let us see an example without catch-block or finally-block

TryWithResourcesWithNoCatchOrFinallyBlock.java

Rule 4: All resource reference variables are implicitly final

  • All resource reference variables declared inside try-with-resources statement are implicitly final
  • That’s we can’t change or re-assign value inside try-block
  • Error: if we try to change it, then compile-time error will be thrown stating “The resource <resource-variable-name> of a try-with-resources statement cannot be assigned

Conclusion:

  • The advantage of using new feature called “try-with-resources” statement is that, programmer doesn’t need to write/code finally-block to close resources explicitly (by doing so, resources will be made available to other users for their operations)
  • New try-with-resources statement is auto-closed, once control reaches to end of try-catch block execution

Related Articles:

References:

Happy Coding !!
Happy Learning !!

Java 7 - Multi-catch block with examples
Java - User-defined Exception or Custom Exception