JLS 11.2.3 says that it is a compile time error if a method body can throw a checked exception and it does not declare the class (or a parent class) in its throws
clause.
In the following code, Throwable
is a checked exception (per JLS 11.1.1) being thrown in the catch
clause of main
:
public class Main {
public static void main(String[] args) {
try {
foo();
} catch (Throwable t) {
throw t;
}
}
public static void foo() {
throw new RuntimeException();
}
}
However, javac compiles it without any errors.
If we change the signature of foo
to declare that it throws Throwable
, we get an error as expected:
public class Main {
public static void main(String[] args) {
try {
foo();
} catch (Throwable t) {
throw t;
}
}
public static void foo() throws Throwable {
throw new RuntimeException();
}
}
$ javac Main.java
Main.java:6: error: unreported exception Throwable; must be caught or declared to be thrown
throw t;
^
1 error
It seems like javac figures out (in the first example) that, since foo
does not declare any checked exceptions, the caught Throwable t
must be an unchecked exception, and so main
only ever rethrows an unchecked exception, and thus it does not need a throws
clause.
Is there anything in the JLS that explains this behaviour?