Java7 is out since a few years & so try-with-resources in Java7.
You might have already seen how this is working in new try-catch blocks.
So below I am just giving one sample to create your autocloseable class to use & you can see the difference,
as you can return exceptions accordingly & which may be useful -
Below is our custom Autocloseable class which we will use in our next class to check the difference & I have put the comments in the code itself which you can read for better understanding & have given the output also-
public class CustomAutoCloseable implements AutoCloseable {
static private boolean isOpen = false;
public CustomAutoCloseable() throws CustomException {
if(isOpen) {
throw new CustomException();
}
isOpen = true;
}
public int add(int a, int b) throws Exception {
if(a < 0 || b < 0)
throw new Exception("Addition Exception......");
return a+b;
}
@Override
public void close() throws Exception {
isOpen = false;
/*if(isOpen)
isOpen = false;
else
throw new Exception("Exception from close()......");*/
throw new Exception("Exception from close()......");
}
}
class CustomException extends Exception {
private static final long serialVersionUID = 1L;
public CustomException() {
super("AutoCloseable Constructor Exception");
}
}
--------------------------------------------------------------------------------------------------
public class Testing {
public static void main(String[] args) throws Exception {
try {
check();
} catch(Exception e) {
System.out.println(e.getMessage());
}
System.out.println("--------------------------------");
try {
check1();
} catch(Exception e) {
System.out.println("Suppressed Exception - " + e.getSuppressed()[0].getMessage());
System.out.println("Main exception - " + e.getMessage());
}
System.out.println("--------------------------------");
try {
check2();
} catch(Exception e) {
System.out.println("Suppressed Exception - " + e.getSuppressed()[0].getMessage());
System.out.println("Main exception - " + e.getMessage());
}
System.out.println("--------------------------------");
try {
check3();
} catch(Exception e) {
// Below API will get no information about the suppressed exception
// as there is no such exception as part of CustomAutoCloseable class
// So it will give RuntimeException if uncommented.
// System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getMessage());
}
System.out.println("--------------------------------");
try {
check4();
} catch(Exception e) {
// Though below API exists but it doesn't get the supressed exception's information
// as not using new try catch block. So it will through RuntimeException if uncommented.
// System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getMessage());
}
}
/**
* Below method is having one exception condition which will arise
* in close() of CustomAutoCloseable & will be returned back from
* finally block below.
* @throws Exception
*/
public static void check() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
System.out.println("In check finally...........");
}
}
/**
* Below method has 2 exception conditions - one from add() & second from close()
* So here exception from add() is more useful but exception from close() will be
* suppressed here and the calling method will get the exception from add() as
* main exception.
* @throws Exception
*/
public static void check1() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable()) {
System.out.println(ca.add(2, -3));
} finally {
System.out.println("In check1 finally...........");
}
}
/**
* Here we are not throwing any separate exception from finally block
* so actual exception from constructor of CustomAutoCloseable will be
* returned back along with the exception from close() as suppressed
* exception.
* @throws Exception
*/
public static void check2() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable();
CustomAutoCloseable ca1 = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
System.out.println("In check2 finally............");
}
}
/**
* Below finally block is throwing exception which is not generating
* from try block, so it will replace the original exception which is
* thrown from constructor of CustomAutoCloseable & we lose this info.
* @throws Exception
*/
public static void check3() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable();
CustomAutoCloseable ca1 = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
throw new Exception("Thrown from check3 finally block.........");
}
}
/**
* Below method has 2 exception conditions - one from add() & second from close()
* as closing twice here. So here exception from add() is more useful but it will
* be replaced by exception close() while returning & we don't get the required
* information while using old try-catch block
* @throws Exception
*/
public static void check4() throws Exception {
CustomAutoCloseable ca = new CustomAutoCloseable();
try {
ca.close();
System.out.println(ca.add(2, -3));
} finally {
System.out.println("In check4 finally............");
ca.close();
}
}
}
---------------------------------------------------------------------------------
Output :-
5
In check finally...........
Exception from close()......
--------------------------------
In check1 finally...........
Suppressed Exception - Exception from close()......
Main exception - Addition Exception......
--------------------------------
In check2 finally............
Suppressed Exception - Exception from close()......
Main exception - AutoCloseable Constructor Exception
--------------------------------
Thrown from check3 finally block.........
--------------------------------
In check4 finally............
Exception from close()......
Note :- If using Java8 or higher, then check this also - Autocleable in Java8
You might have already seen how this is working in new try-catch blocks.
So below I am just giving one sample to create your autocloseable class to use & you can see the difference,
as you can return exceptions accordingly & which may be useful -
Below is our custom Autocloseable class which we will use in our next class to check the difference & I have put the comments in the code itself which you can read for better understanding & have given the output also-
public class CustomAutoCloseable implements AutoCloseable {
static private boolean isOpen = false;
public CustomAutoCloseable() throws CustomException {
if(isOpen) {
throw new CustomException();
}
isOpen = true;
}
public int add(int a, int b) throws Exception {
if(a < 0 || b < 0)
throw new Exception("Addition Exception......");
return a+b;
}
@Override
public void close() throws Exception {
isOpen = false;
/*if(isOpen)
isOpen = false;
else
throw new Exception("Exception from close()......");*/
throw new Exception("Exception from close()......");
}
}
class CustomException extends Exception {
private static final long serialVersionUID = 1L;
public CustomException() {
super("AutoCloseable Constructor Exception");
}
}
--------------------------------------------------------------------------------------------------
public class Testing {
public static void main(String[] args) throws Exception {
try {
check();
} catch(Exception e) {
System.out.println(e.getMessage());
}
System.out.println("--------------------------------");
try {
check1();
} catch(Exception e) {
System.out.println("Suppressed Exception - " + e.getSuppressed()[0].getMessage());
System.out.println("Main exception - " + e.getMessage());
}
System.out.println("--------------------------------");
try {
check2();
} catch(Exception e) {
System.out.println("Suppressed Exception - " + e.getSuppressed()[0].getMessage());
System.out.println("Main exception - " + e.getMessage());
}
System.out.println("--------------------------------");
try {
check3();
} catch(Exception e) {
// Below API will get no information about the suppressed exception
// as there is no such exception as part of CustomAutoCloseable class
// So it will give RuntimeException if uncommented.
// System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getMessage());
}
System.out.println("--------------------------------");
try {
check4();
} catch(Exception e) {
// Though below API exists but it doesn't get the supressed exception's information
// as not using new try catch block. So it will through RuntimeException if uncommented.
// System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getMessage());
}
}
/**
* Below method is having one exception condition which will arise
* in close() of CustomAutoCloseable & will be returned back from
* finally block below.
* @throws Exception
*/
public static void check() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
System.out.println("In check finally...........");
}
}
/**
* Below method has 2 exception conditions - one from add() & second from close()
* So here exception from add() is more useful but exception from close() will be
* suppressed here and the calling method will get the exception from add() as
* main exception.
* @throws Exception
*/
public static void check1() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable()) {
System.out.println(ca.add(2, -3));
} finally {
System.out.println("In check1 finally...........");
}
}
/**
* Here we are not throwing any separate exception from finally block
* so actual exception from constructor of CustomAutoCloseable will be
* returned back along with the exception from close() as suppressed
* exception.
* @throws Exception
*/
public static void check2() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable();
CustomAutoCloseable ca1 = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
System.out.println("In check2 finally............");
}
}
/**
* Below finally block is throwing exception which is not generating
* from try block, so it will replace the original exception which is
* thrown from constructor of CustomAutoCloseable & we lose this info.
* @throws Exception
*/
public static void check3() throws Exception {
try(CustomAutoCloseable ca = new CustomAutoCloseable();
CustomAutoCloseable ca1 = new CustomAutoCloseable()) {
System.out.println(ca.add(2, 3));
} finally {
throw new Exception("Thrown from check3 finally block.........");
}
}
/**
* Below method has 2 exception conditions - one from add() & second from close()
* as closing twice here. So here exception from add() is more useful but it will
* be replaced by exception close() while returning & we don't get the required
* information while using old try-catch block
* @throws Exception
*/
public static void check4() throws Exception {
CustomAutoCloseable ca = new CustomAutoCloseable();
try {
ca.close();
System.out.println(ca.add(2, -3));
} finally {
System.out.println("In check4 finally............");
ca.close();
}
}
}
---------------------------------------------------------------------------------
Output :-
5
In check finally...........
Exception from close()......
--------------------------------
In check1 finally...........
Suppressed Exception - Exception from close()......
Main exception - Addition Exception......
--------------------------------
In check2 finally............
Suppressed Exception - Exception from close()......
Main exception - AutoCloseable Constructor Exception
--------------------------------
Thrown from check3 finally block.........
--------------------------------
In check4 finally............
Exception from close()......
Note :- If using Java8 or higher, then check this also - Autocleable in Java8