Interesting Java 7 feature – try-with-resources statement

try-with-resources

Java developers often need to work with I/O resources like files, sockets, connections that must be closed after use. Prior to JDK 7 version, only right way is to close them in “finally” block so that even if exception occurs while accessing the resource, it should close gracefully without causing I/O issues to the running program or external system. With JDK7, an interesting concept is introduced where JRE closes the resources once the try block is executed. This approach not only makes the code simpler but also makes it less error prone in case developer forgets to close the connection in finally block.

Below example shows a code snippet with finally block where database connection and statement is explicitally closed in the finally block irrespective of the fact that try block statements are executed or not. To avoid any possible null pointer exceptions, there are null checks in the finally blocks.

 

Resource handling example prior to Java 7

 public void makeDBCall() {     Connection conn = null;     Statement stmt = null;     ResultSet rs = null;      try {         // JDBC driver         Class.forName("oracle.jdbc.OracleDriver");         // Get connection         conn = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/xe", USER, PASSWORD);         stmt = conn.createStatement();         String sql = "select id, firstName, lastName from Customer";         rs = stmt.executeQuery(sql);         while (rs.next()) {             System.out.println(rs.getInt("Id"));             System.out.println(rs.getString("firstName"));             System.out.println(rs.getString("lastName"));         }     } catch (ClassNotFoundException e) {             e.printStackTrace();     } catch (SQLException e) {         e.printStackTrace();     } finally {         try {             if (rs != null) {                 rs.close();             }             if (stmt != null) {                 stmt.close();             }             if (conn != null) {                 conn.close();             }         } catch (Exception ex) {             ex.printStackTrace();         }     } }

 

 

 

Resource handling example in Java 7 or later releases

 public void makeDBCall() {      String sql = "select id, firstName, lastName from Customer";      try(Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/xe",          USER, PASSWORD); Statement stmt = conn.createStatement()) {          // Get connection         ResultSet rs = stmt.executeQuery(sql);         while (rs.next()) {             System.out.println(rs.getInt("Id"));             System.out.println(rs.getString("firstName"));             System.out.println(rs.getString("lastName"));         }     } catch (SQLException e) {         e.printStackTrace();     }  }

Important thing to Note – Objects created in try-with-block statment are final and can’t be re-initialized in the try block.

 

For a resource to be used in try-with-resource statement, it should implement java.lang.AutoCloseable and all it’s member objects should implement java.io.Closeable.

 

Some of the frequently used Interfaces/Classes that extend/implement java.lang.Autocloseable 

BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, FileInputStream, FileOutputStream, FileLock, FileSystem, FileWriter, ResultSet, Connection, RowSet

 

What if exception occurs in try-with-resource statement or try block?

1. If exception occurs in try-with-resouce statement while creating resources, it’s caught in the catch statement and application can handle it based on the requirement. In the below example exception in try-with-resource statement is handled in catch statement below.

 public void makeDBCall() {      String sql = "select id, firstName, lastName from Customer";      try(Connection conn = DriverManager.getConnection(CONN_STRING, USER, PASSWORD);          Statement stmt = conn.createStatement()) {          // Get connection         ResultSet rs = stmt.executeQuery(sql);         while (rs.next()) {             System.out.println(rs.getInt("Id"));             System.out.println(rs.getString("firstName"));             System.out.println(rs.getString("lastName"));         }     } catch (SQLException e) {         // Exception occurred in try-with-resource statement while creating resource gets caught here         System.out.println("SQL exception occurred while creating resource");         e.printStackTrace();     } }

 

2. If exception occurs while closing the resource(s) created in try-with-resource block,  it can also be caught in the catch block of try statement. In below example, a CustomResource class is created which implements AutoCloseable and throws Exception in close method. In makeDBCall method, exception is thrown while trying to close the resouce after the execution and statement “—-Exception occurred while closing custom resource—-” is printed.

 public class CustomResource implements AutoCloseable {      /**      * Custom resource that throws exception in close method.      *      * @throws Exception      */     @Override     public void close() throws Exception {         throw new Exception();     } }
 public void makeDBCall() {      String sql = "select id, firstName, lastName from Customer";      try(Connection conn = DriverManager.getConnection(CONN_STRING, USER, PASSWORD);          Statement stmt = conn.createStatement(); CustomResource resource = new CustomResource()) {          // Get connection         ResultSet rs = stmt.executeQuery(sql);         while (rs.next()) {             System.out.println(rs.getInt("Id"));             System.out.println(rs.getString("firstName"));             System.out.println(rs.getString("lastName"));         }      } catch (SQLException e) {         System.out.println("SQL exception occurred while creating resource");         e.printStackTrace();     } catch (Exception e) {         System.out.println("----Exception occurred while closing custom resource----");         e.printStackTrace();     } }

{jcomments on}


Leave a Reply

Your email address will not be published. Required fields are marked *