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:
- All resources declared as part of try-with-resources statement must be AutoCloseable (i.e.; all resources must implements java.lang.AutoCloseable interface)
- Multiple resources can be declared inside try-block argument; but they are all must be separated by semi-colon (;)
- 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
- 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:
- Java – Exception Handling
- Java – Exception Hierarchy
- Java – 5 important keywords in Java Exception handling
- Java – Runtime mechanism, what happens when exception is thrown ?
- Java – Checked Exception v/s Unchecked Exception
- Java – Exception propagation
- Java – try-catch block
- Java – finally block
- Java – try with multiple catch blocks
- Java – Nested try-catch block
- Java – Returning value from method having try-catch-finally blocks
- Java – return statement with finally block
- Java – final v/s finally v/s finalize
- Java – Various methods to print exception information
- Java – throw keyword
- Java – throws keyword
- Java – throw v/s throws
- Java – Difference between throws clause and try-catch-finally block
- Java – Rules for Exception handling w.r.t Method Overriding
- Java – User-defined or Custom exception
- Java – Difference between ClassNotFoundException v/s NoClassDefFoundError
- Java – Top Exception and Error
- Java – Interview question and answers on Exception Handling
- Java 7 – try with resources
- Java 7 – multi-catch block
References:
- http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
- http://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/
- https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-11.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/ArithmeticException.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html
- http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html
- http://www.oracle.com/technetwork/java/effective-exceptions-092345.html
- http://otfried.org/courses/cs206/slides/slides-stackframes.pdf
Happy Coding !!
Happy Learning !!