Java 为什么这两个重试异常都会创建编译器错误?

Java 为什么这两个重试异常都会创建编译器错误?,java,exception,exception-handling,throws,Java,Exception,Exception Handling,Throws,为什么抛出outerE生成编译错误?我知道,抛出e不应生成编译器错误,因为 它们是相同的Exception对象,但一个仅在catch块内,一个在try-catch块外 这两种方法都不应该产生编译器错误吗?或者,至少,两者的行为方式相同 static void preciseRethrowTest() { Exception outerE; try { } catch (Exception e) { outerE = e;

为什么
抛出outerE生成编译错误?我知道,
抛出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
    }
}

我使用的是Java1.8.0_51。(Java 7中引入了精确的重新调用)

问题是,检查的异常无法到达catch块;编译器足够聪明,可以实现这一点

考虑这一点:

public class RethrowTest {
  static void preciseRethrowTest() {
    Exception outerE;
    try {
      throw new Exception();
    } catch (Exception e) {
      outerE = e;

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

      throw e; // Now a compiler error *is* generated.
    }
  }
}

这确实会引发编译器错误,因为现在可以通过选中的异常访问代码。

您的方法没有
抛出声明

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

这里,您正在尝试重新分配

outerE = e;
// Compilation error here. Unhandled exception type Exception
// throw outerE; 
并通过另一个变量重新显示异常。编译器不需要花那么多时间来计算
outerE
中的值。它可以是你身上的例外,也可以是别的。编译器会确保安全并阻止您执行此操作

以代码为例

if (Math.random() < 0.5) 
    outerE = e;
else 
    outerE = new IOException("nope");
throw outerE; 
if(Math.random()<0.5)
outerE=e;
其他的
outerE=新IOException(“nope”);
扔外衣;
编译器无法知道存储在
outerE
中的
Exception
值是您捕获的未检查的异常,还是您从其他地方分配的其他可能已检查的异常