带返回的 Try-finally 块不会引发异常

Ant*_*Roy 0 java exception try-finally

在这段代码中,main 方法的 Catch 不会捕获运行时异常。执行finally块后,它应该已经转到main的异常块,但它没有。

 class FinallyDemo {
    static int m1(){
        try{
            System.out.println("Inside m1");
            throw new RuntimeException("hi");
        }
        finally {
            System.out.println("m1 finally");
            return 5;
        }
    }
    public static void main(String[] args) {
        try{
            System.out.println(m1());
        }catch (Exception e){
            System.out.println("main caught: "+ e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Inside m1
m1 finally
5
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 13

(如评论中所述,所编写的代码甚至无法编译,但可以在不更改问题核心的情况下进行修复。)

它应该进入 main 的异常块,但它没有。

不,它的行为与规范第 14.20.2 节完全相同。那里有很多路径,但这里应用的路径是:

  • ...
  • 如果try块的执行由于值 V 的抛出而突然完成
    • ...
    • 如果 V 的运行时类型与catchtry 语句的任何子句的可捕获异常类的赋值不兼容,则finally执行该块
      • ...
      • 如果finally块因 S 原因突然完成,则try语句因 S 原因突然完成(并且值 V 的抛出被丢弃并忘记)。

根据第 14.1 节return,语句算作“突然完成” 。所以整个 try/finally 语句由于“返回一个值”而突然完成,就好像没有抛出异常一样。

如果您希望异常传播到try/finally语句之外,请不要returnfinally块中使用语句。