try/finally without catch and return value

我有一个程序如下:

public class Main {
    public static void main(String[] args)throws Exception
    {
        int res = test();
        System.out.println("after call , res = " + res) ;
    }

    public static int test()throws Exception
    {
        try
        {
            return 10/0;
        }
        finally
        {
            System.out.println("finally") ;
        }
    }
}

运行上述程序后,在控制台中看到以下结果:

finally
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Main.test(Main.java:17)
    at Main.main(Main.java:7)

此行为是正常的,因为异常会抛出到 main 方法。

然后我更改代码如下:

public class Main {
    public static void main(String[] args)throws Exception
    {
        int res = test();
        System.out.println("after call , res = " + res) ;
    }

    public static int test()throws Exception
    {
        try
        {
            return 10/0;
        }
        finally
        {
            System.out.println("finally") ;
            return 20;
        }
    }
} 

当运行上面的程序时,我在控制台中看到以下结果:

finally
after call , res = 20

我的问题与第二种格式有关。为什么在返回时最终阻塞,异常没有抛出到main方法?


答案 1

当引发异常时,它将首先通过最终的块。

如果您的块没有返回或抛出任何内容,则传递原始异常。finally

另一方面,如果块返回一个值,则异常将不再传播。finally


答案 2

最后看看尝试捕获的执行。

来自 java 语言规范 -jls-14.20.2

如果运行时类型 V 的赋值与 try 语句的任何 catch 子句的可捕获异常类不兼容,则执行 finally 块。然后有一个选择:

如果最终块正常完成,则 try 语句由于值 V 的抛出而突然完成。

如果最终的块由于原因 S 而突然完成,则 try 语句由于原因 S 而突然完成(并且值 V 的抛出被丢弃并被遗忘)。


推荐