java 编译器是否优化了无法访问的异​​常捕获分支?

Does java compiler optimize unreachable exception catch branches?

为什么是代码

void methodThrowsException() /*throws  Exception*/{
    try {
      // throw new Exception();
    } catch (Exception e) {
      throw e;
    }
}

编得好吗? AFAIK 编译器不会分析代码是否会抛出异常。 这里很明显 throw e; 永远不会 运行(由于注释 // throw new Exception();),但为什么编译器知道这一点?

javac 编译器确实没有做很多优化。但是 简单 死代码检测和优化仍然是可能的。

在您的示例中:编译器可以轻松检测到 try 块为空。空的 try 块不能抛出,所以所有的 catch 块代码本质上是 dead

所以编译器 可以 进入并简单地将整个 try/catch 一起放到这里。然后就没有什么可以抛出异常了。

其中,当我们使用 javap 时,正是我们在字节码中发现的:

  void methodThrowsException();
    Code:
       0: return

是的,另一个答案是完全正确的:这只能以这种方式工作,因为您使用的是 Exception,更具体(已检查)的子类将导致编译器错误。

编译器将检测未抛出的特定检查异常,例如

void methodThrowsException() {
    try {
    } catch (URISyntaxException e) {
        throw e;
    }
}

会导致编译错误:

exception java.net.URISyntaxException is never thrown in body of corresponding try statement

但它不会检查运行时异常,或像 ExceptionErrorThrowable 这样的异常层次根类型。 JLS 11.2.3. Exception Checking.

中对此进行了解释