为什么这些重新抛出的异常中的任何一个都会产生编译器错误?

Ven*_*aju 12 java exception-handling exception throws

为什么会throw outerE;生成编译错误?我知道throw e;由于精确的重新抛出功能,不应该生成编译器错误.

它们是相同的Exception对象,但是一个catch仅限于块内部,一个作用于try-catch块之外.

这些都不应该生成编译器错误吗?或者,至少,两者的行为方式相同?

static void preciseRethrowTest()
{
    Exception outerE;
    try
    {

    }
    catch (Exception e)
    {
        outerE = e;

        // Compilation error here. Unhandled exception type Exception
        // throw outerE; 

        throw e; // No compiler error
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Java 1.8.0_51.(精确的重新抛出在Java 7中引入)

Sot*_*lis 6

您的方法没有throws声明.

编译器现在足够聪明,可以确定您的try块不能抛出任何已检查的异常.因此,必须取消选中捕获并绑定到块中Exception参数的任何异常catch.由于它们未被检查,您可以在闲暇时重新抛出它们(并且它们不需要throws声明).

在这里,你试图重新分配

outerE = e;
// Compilation error here. Unhandled exception type Exception
// throw outerE; 
Run Code Online (Sandbox Code Playgroud)

并通过另一个变量重新抛出异常.编译器并没有走得那么远,无法弄清楚它的价值outerE.它可能是您捕获的异常,也可能是其他异常.编译器可以安全地使用它并阻止你这样做.

考虑像

if (Math.random() < 0.5) 
    outerE = e;
else 
    outerE = new IOException("nope");
throw outerE; 
Run Code Online (Sandbox Code Playgroud)

编译器无法知道Exception存储的值outerE是您捕获的未经检查的异常还是从其他位置分配的其他可能已检查的异常.