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?