Learning JDK 7 Features Part 3: Try With Resource

Today we follow some standard coding conventions so that code should easy to read and maintainable or  i can say " Code should look beautiful ". But there are some cases where we find our code is cluttered or duplicated. Its more often with Exception Handlers, Streams and JDBC calls i.e. opening and closing streams/connections and multiple catch handlers. Java 7 comes to rescue us from this duplication and is succeeded in it.

Before Java 7, to cloase a resource, we write a final block and close every resource in it. but some times the finally block become large and cluttered. Take a look at the code below:-
finally {
            try {
                if (resultSet != null)
                    resultSet.close();
            }
            catch(Exception e) {}
            finally {
                try {
                    if (statement != null)
                        statement.close();
                }
                catch(Exception e) {}
                finally {
                    connection.close();
                }
            }
        }
So here we see that we close the every stream and write catch block for every close which makes the code cluttered. Also there is good chance that one forget to close the resource and it stays in memory forever.

With Java 7, there is no need to close the resource manually . Java do it for you. But there is catch. One must aware of catching mechanism, which I'll discuss later. Lets look at updated code:-
public static void printEmployees(Connection con) 
 {
  String query = "select ID, NAME, Location, Employee";

  try (Statement stmt = con.createStatement();
    ResultSet resultset = stmt.executeQuery(query);)
  {
   while (resultset.next()) {
    String id = resultset.getString("ID");
    String name = resultset.getString("NAME");
    String loc = resultset.getString("Location");
    System.out.println(id + ", " + name + ", " + loc);
   }

  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
}

We declare the objects/resources in try, as shown in code. Now, there is no need to write finally block to close the resources. Now the question arises, what type of object should consider as resource. Java comes up with a new interface to solve the problem; is "AutoCloseable". Those classes which implements the interface is considered as a resource, can used inside try. Below is an example to declare a class as resource and used try as resource :-
public class  TestNewTryCatch{

 public static void main(String[] args) {

  try(MyResource res = new MyResource())
  {
   res.execute();
  }  
  catch (Exception e  ) {}
 }
}

class MyResource implements AutoCloseable
{
 @Override
 public void close() throws Exception {
  System.out.println("In close");
 }
 public void execute() throws Exception
 {
  System.out.println("In Execute");
 }
}

Exception handling handles differently. If an exception is thrown in try block and one or more exceptions are thrown from try with resource than exceptions that corresponds to try with resource are surpressed. We can retrieved the surpressed exceptions using throwable.getSuppressed() . Lets see with an example:-
public class TestNewTryCatch{

 public static void main(String[] args) {
  try(MyResource res = new MyResource() )
  {
   res.execute();
  }  
  catch (Exception e  ) {
   System.out.println("In exception-->" + e.getMessage());
   Throwable ht[] =e.getSuppressed();
   for(Throwable t:ht)
   {
    System.out.println(t.getClass());
    System.out.println(t.getMessage());
   }
  }
 }
}
class MyResource implements AutoCloseable
{
 @Override
 public void close() throws Exception {
  System.out.println("In close");
  throw new MyException("Test2");
 }

 public void execute() throws Exception
 {
  throw new RuntimeException("EXECUTE Test");
 }

}

class MyException extends Exception
{
 public MyException(String string) {
  super(string);
 } 
}
Output:-
In close
In exception-->EXECUTE Test
class MyException
Test2
Hope this article puts some light into the new try feature. Throw a comment in case i miss something or have some query.

Comments

  1. Very nice and illustrious article

    ReplyDelete
  2. Just to double check:
    If an exception occurs during resource initialization (e.g. if MyResource res = new MyResource() threw an exception), it would be handled in catch normally, right?

    ReplyDelete
  3. Exactly, it will be handled by catch normally. Also, as the resource doesn't created, close() function will not be executed.

    ReplyDelete

Post a Comment

Popular posts from this blog

When to use getClass() and instanceOf in Java

How class.forName loads the Database Driver in JDBC

Why Time gets truncated with ResutSet getDate() function.