Java 1.7 introduces a new language feature for its very well-known try-catch block called try-with-resources. Let’s understand how this new feature works and how it would simplify resources management in Java (e.g. automatically close/release resources after used).

 

1. Basic Java try-with-resources examples

Consider the following classic example to copy one file to another:

public void copyFile(File sourceFile, File destFile)
		throws IOException {

		FileChannel sourceChannel = null;
		FileChannel destChannel = null;

	try {
		sourceChannel = new FileInputStream(sourceFile).getChannel();
		destChannel = new FileOutputStream(destFile).getChannel();
		sourceChannel.transferTo(0, sourceChannel.size(), destChannel);
	} finally {
		if (sourceChannel != null) {
			sourceChannel.close();
		}
		if (destChannel != null) {
			destChannel.close();
		}
	}
}
Notice there are two tasks we have to do explicitly with this code:

  • Nullify (initialize to null) the two objects sourceChanneland destChannel before using them in the try body:
    FileChannel sourceChannel = null;
    FileChannel destChannel = null; 
  • Close these resources in the finally clause:
if (sourceChannel != null) {
	sourceChannel.close();
}
if (destChannel != null) {
	destChannel.close();
}
This kind of tasks would repeat again and again while working with other closeable resources like database connections, network/database connection, etc. To simplify this repetitive stuff, we can re-write the above copyFile() method with the new try-with-resources feature as follows:

public void copyFile(File sourceFile, File destFile)
		throws IOException {

	try (
		FileChannel sourceChannel = new FileInputStream(sourceFile).getChannel();
		FileChannel destChannel = new FileOutputStream(destFile).getChannel();
	) {

		sourceChannel.transferTo(0, sourceChannel.size(), destChannel);

	}
}
This new version is much simpler than the previous one, cool huh? Notice there is no catch or finally clause. Behind the scene, the Java compiler will generate the catch and finally clauses for the try-with-resources statement automatically (translation). The resource must be a subtype of the java.lang.AutoCloseable interface (new interface in Java 1.7) so the compiler can generate code to invoke the close() method on the resource. Otherwise a compilation error will be reported.

So far the syntax for this basic try-with-resources statement is as follows:

try (

       Resource initialization #1;

       Resource initialization #2;

       ...

       Resource initialization #n;

) {

       // body

}

Each resource initialization is a statement which is separated by a semicolon. The resources are closed in the reverse order in which they were initialized. And there is no catch or finally clause.

 

2. Extended Java try-with-resources examples



Another version of the try-with-resources statement has at least one catch and/or finally clause as follows:

try (

                   Resource initialization #1;

                   Resource initialization #2;

                   ...

                   Resource initialization #n;

          ) {

                   // body

} catch (Exception e) {

           // catch body

 } finally {

           // finally body

 }

It’s easy to recognize that this syntax wraps a try-with-resources statement within a normal try-catch-finally block that allows us to catch exceptions might be thrown during initialization and closing of the resources. Consider a classic example that connects to a database:

public void connectDatabase(String url, String user, String password) {

	Connection conn = null;

	try {

		conn = DriverManager.getConnection(url, user, password);

		if (conn != null) {
			System.out.println("Connected to the database");
		}

	} catch (SQLException ex) {
		System.out.println("An error occurred. Maybe user/password is invalid");
		ex.printStackTrace();
	} finally {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException ex) {
				ex.printStackTrace();
			}
		}
	}
}
It can be re-written using the extended try-with-resources statement like this:

public void connectDatabase(String url, String user, String password) {

	try (Connection conn = DriverManager.getConnection(url, user, password)) {

		if (conn != null) {
			System.out.println("Connected to the database");
		}
	} catch (SQLException ex) {
		System.out.println("An error occurred. Maybe user/password is invalid");
		ex.printStackTrace();
	}
} 


3. The AutoCloseable interface

This new interface has been introduced since Java 1.7 as a super-interface of all classes/interfaces which represent the resources in the try-with-resources statement. So lots of interfaces and classes in the Java SE API have been refactored to implement the java.lang.AutoCloseable interface, mostly are the I/O-related classes in the package java.io.*, java.nio.*, java.sql.*, etc. If you use your own custom classes as the resources, remember to have them implement the AutoCloseable interface and its close() method.

 

Related Tutorials:

 

Other Recommended Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Add comment