Java allows me to compile the following code without any issues:
public class Test {
public static void main(String[] args){
try {
throw new RuntimeException();
} catch (Exception e) {
throw e;
}
}
}
Even though java.lang.Exception is a checked exception. Meaning that I am rethrowing unchecked exception as checked and get away with that.
Most likely Java compiler is able to figure out that no checked exception is thrown in the try block, but I can't find the section in the specification that backups that.
Can one rely on this behavior and starting from which JDK version?
Update: This class doesn't compile with Java 1.6.0_38 with the following message:
Test.java:6: unreported exception java.lang.Exception; must be caught or declared to be thrown
throw e;
^
1 error
It looks like that this is one of the effects of the enhancement in Java 7: Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking. See section "Rethrowing Exceptions with More Inclusive Type Checking."
The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException. Even though the exception parameter of the catch clause, e, is type Exception, the compiler can determine that it is an instance of either FirstException or SecondException.
Please note, that the following will not compile though even in Java 7 and above:
public class Test {
public static void main(String[] args){
try {
throw new RuntimeException();
} catch (Exception e) {
Exception e1 = e;
throw e1;
}
}
}
Because:
This analysis is disabled if the catch parameter is assigned to another value in the catch block.