Why can a caught Throwable be rethrown without declaring Throwable in the method's throws clause?

50 views Asked by At

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?

0

There are 0 answers