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