Java- Exception handling Enhancements

Java 1.7 Exception handling Enhancements

Java try-with-resources

  • Before java 7, we had to use finally blocks to write closing statements manually, to clean up the resources. Finally blocks were not mandatory, but resource cleanup was to prevent the system from being corrupt.

  • With java 7, no need to explicit resource cleanup. It’s done automatically.

  • Automatic resource cleanup done when initializing resource in try block try ( resource ).

  • Cleanup happens because of new interface AutoCloseable. Its close method is invoked by JVM as soon as try block finishes.

  • In java 7, we have a new super interface java.lang.AutoCloseable. This interface has one method:
    void close() throws Exception;
    

    All File.IO.* Streams(InputStream,OutputStream,) & ResultSet by default implements AutoClosable interface.

  • When we open any such AutoCloseable resource in special try-with-resource block, immediately after finishing the try block, JVM calls this close() method on all resources initialized in -try()” block.

  • If you want to use this in custom resources, then implementing AutoCloseable interface is mandatory. otherwise program will not compile.


Case 1 : Try-with- Single resource

public class Test {
  public static void main(String args[]) {
    try (FileInputStream input = new FileInputStream("file.txt")) {

      int data = input.read();
      while (data != -1) {
        System.out.print((char) data);
        data = input.read();
      }

    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}
Satya
shiva
rma
hanu
vinay
govind
ramesh

The opened resource will be limited to inner try block, so not available for catch/final

try (FileInputStream input = new FileInputStream("file.txt")) {
 
 } catch (Exception e) { 	 
 	e.printStackTrace();
 	input.close();
 }finally {
 	input.close();
 }
Test.java:18: error: cannot find symbol
                        input.close();
                        ^


Case 2: Try-with- Multiple Resources
we can declare it by line by line separated by semicolons;

public class Test {
  public static void main(String args[]) {
    try (
    FileInputStream input = new FileInputStream("file.txt");
    FileOutputStream output = new FileOutputStream("file.txt")
    ) 
    {
      // Write to file
      for (int i = 0; i < 10; i++) {
        output.write(i);
      }

      // Read from File
      int data = input.read();
      while (data != -1) {
        System.out.print(data);
        data = input.read();
      }

    } catch(Exception e) {
      e.printStackTrace();
    } finally {

    }
  }
}


Case 3: Try-with- Resources – Exception in Try block If a try block throws an exception and one or more exceptions are thrown by the try-with-resources, the exceptions thrown by try-with-resources are suppressed.

You can get these suppressed exceptions by using the Throwable.getSuppress() method of Throwable class.

public class Test {
  public static void main(String args[]) {
    try (FileInputStream input = new FileInputStream("nofile.txt");) {

} catch(Exception e) {
      System.out.println("Catch block");
      e.printStackTrace();
    } finally {
      System.out.println("finally");
    }
  }
}
Catch block
java.io.FileNotFoundException: nofile.txt (The system cannot find the path specified)	
	at core.Test.main(Test.java:9)
finally


Case 4: Java9 Enhancement - Resource declared outside the try block
In Java 7, try-with-resources has a limitation that requires resource should declare within try block only otherwise compiler generates an error: <identifier> expected.

FileInputStream input = new FileInputStream("file.txt");
 try (input) {
 }
error: <identifier> expected
    try(input)

To deal with this error, try-with-resource is improved in Java 9 and now we can use reference of the resource that is not declared locally.

public class Test {
  public static void main(String args[]) throws IOException {
    FileInputStream input = new FileInputStream("file.txt");
    try (input) {

      int data = input.read();
      while (data != -1) {
        System.out.print((char) data);
        data = input.read();
        input.close();
      }

    } catch(Exception e) {
      e.printStackTrace();
      input.close();
    } finally {
      input.close();
    }
  }
}

Now we can access input varible in catch and finally block


Catch with Multiple Exception classes

From Java 7 onwards, you can catch multiple exceptions in single catch block using ( | ) symbol.

catch(NullPointerException | IndexOutOfBoundsException ex)
  {
           Ex.printStackTrace();
  }
  • If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.

  • The Exceptions must be in same level of Hierarchy.

    catch(NullPointerException | Exception ex)
            {
                throw ex;
            }
    The exception NullPointerException is already caught by the alternative