try/finally没有catch和返回值

Sam*_*Sam 24 java exception-handling try-catch-finally

我有一个程序如下:

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") ;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

这种行为是正常的,因为抛出到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;
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

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

finally
after call , res = 20
Run Code Online (Sandbox Code Playgroud)

我的问题与第二种格式有关.为什么在finally块中返回时,异常没有抛到main方法?

bvd*_*vdb 13

抛出异常时,它将首先通过您的finally块.

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

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


Sur*_*tta 8

最后看一下try catch的执行情况.

来自java语言规范-jls-14.20.2

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

如果finally块正常完成,那么try语句会因为抛出值V而突然完成.

如果finally块由于原因S而突然完成,则try语句突然完成,原因是S(并且丢弃并抛弃了值V的抛出).


flo*_*flo 7

来自JLS(强调我的):

如果由于抛出值V而突然完成try块的执行,则有一个选择:
[...]
如果V的运行时类型不与任何catch子句的可捕获异常类分配兼容try语句,然后执行finally块.然后有一个选择:

  • 如果finally块正常完成,那么try语句会因为抛出值V而突然完成.

  • 如果finally块由于原因S而突然完成,则try语句突然完成,原因是S(并且丢弃并抛弃了值V的抛出).

这意味着如果你returnfinally块中,该方法返回而不抛出异常.

此外return,还有其他状态因素可能导致finally阻止突然完成并忘记异常.它们在JLS第14.1节中定义.基本上,它是break,continue,return或者一个异常(或者由语句/方法引发或引起的).然后完整的try/catch/finally块以此原因完成.

在规范中还有一些更多的情况try/catch/finally,特别是如果没有异常或存在匹配的catch子句.它归结为finally节奏catch节拍try.