将 RuntimeException 作为异常重新抛出

Rethrowing RuntimeException as Exception

Java 允许我毫无问题地编译以下代码:

public class Test {
    public static void main(String[] args){
        try {
            throw new RuntimeException();
        } catch (Exception e) {
            throw e;
        }
    }
}

即使 java.lang.Exception 是检查异常。这意味着我将重新抛出未经检查的异常作为已检查并摆脱它。

很可能 Java 编译器能够发现 try 块中没有抛出受检异常,但我在规范中找不到备份该异常的部分。

是否可以依赖此行为并从哪个 JDK 版本开始?

更新: 此 class 无法使用 Java 1.6.0_38 编译,并显示以下消息:

Test.java:6: unreported exception java.lang.Exception; must be caught or declared to be thrown
            throw e;
            ^
1 error

看来这是Java7:Catching Multiple Exception Types and Rethrowing Exceptions with Improved 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.

请注意,即使在 Java 7 及更高版本中,以下内容也不会编译:

public class Test {
    public static void main(String[] args){
        try {
            throw new RuntimeException();
        } catch (Exception e) {
            Exception e1 = e;
            throw e1;
        }
    }
}

因为:

This analysis is disabled if the catch parameter is assigned to another value in the catch block.