I am having trouble understanding how precise rethrow works in Java 7 and later versions. As pointed out in https://www.theserverside.com/tutorial/OCPJP-Use-more-precise-rethrow-in-exceptions-Objective-Java-7, in Java 7 and later versions we can use the throws
clause, in a method declaration, with a comma-separated list of specific exceptions that the method could throw. If all these exceptions are subtypes of the general exception java.lang.Exception
, we will be able to catch any of them in a catch block that catches this supertype, while letting client code (eg. a caller method) to know which of the possible subtypes exceptions actually occurred.
Initially, I thought that in order to let know client code which exception actually occurred, we needed to specify the list of specific exceptions in the throws
clause. Nevertheless, in the following example the client code (the main()
method) seems able to retrieve that information, even if we only specify the exception java.lang.Exception
in the throws
clause of the called method. Therefore, my question is:
Why the following code outputs the same, regardless of whether the throws
clause of the method runException()
is throws ExceptionA, ExceptionB
or throws Exception
?
I am using Oracle JVM-12 in Eclipse. Thanks in advance!
class ExceptionA extends Exception{}
class ExceptionB extends Exception{}
public class RethrowingAndTypeChecking{
public static void runException(char what) throws Exception{
//public static void runException(char what) throws ExceptionA, ExceptionB{
try{
if(what == 'A')
throw new ExceptionA();
else if (what == 'B')
throw new ExceptionB();
}
catch(Exception e){
throw e;
}
}
public static void main (String args[]){
char ch;
for (int i=0;i<2;i++) {
if(i==0) ch='A';
else ch = 'B';
try{
runException(ch);
}
catch(ExceptionA e){
System.out.print("In main(), 'catch(ExceptionA e){}', caught exception: " + e.getClass());
}
catch(ExceptionB e){
System.out.print("In main(), 'catch(ExceptionB e){}', caught exception: " + e.getClass());
}
catch(Exception e){
System.out.print("In main(), 'catch(Exception e){}', caught exception: " + e.getClass());
}
System.out.println();
}
}
}
output:
In main(), 'catch(ExceptionA e){}', caught exception: class ExceptionA
In main(), 'catch(ExceptionB e){}', caught exception: class ExceptionB