0

我知道即使代码抛出异常或者它成功完成,finally 块也会执行,现在我怀疑是这段代码

返回 40

这很明显,但现在如果我

评论返回 40;

它返回 10

谁能帮我理解 JVM 如何返回 10 为什么它不抱怨说该函数应该返回一个值。

public class ExceptionTest {
        public static void main(String[] args) {
        int i=  returnSomething();
        System.out.println(i);
        }
    
        private static int returnSomething() {
            
            try{
                System.out.println("try");
                return 10;
            }
            catch(Exception e)
            {
                return 20;
            }
            finally
            {
                System.out.println("finally ");
                return 40;
            }
        }
    
    }
4

4 回答 4

2

就在块中执行之前returntry控制权被转移到finally块中。在执行finally块时,函数返回,除非return在 finally 块本身中有 a。

因此,函数在 finally 块中返回40时返回,而在 finally 块中没有返回时返回块中的值。returntry


不建议在街区finally返回。

于 2013-10-23T04:58:57.393 回答
1

根据 Java 语言规范, 第 14.20.2 节

通过首先执行 try 块来执行带有 finally 块的 try 语句。然后有一个选择:

  • 如果try块的执行正常完成,则执行finally块,然后有一个选择:
    • 如果 finally 块正常完成,则 try 语句正常完成。
    • 如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成。

...

  • 如果 try 块的执行由于任何其他原因 R 突然完成,则执行 finally 块,然后有一个选择:
    • 如果 finally 块正常完成,则 try 语句由于原因 R 突然完成。
    • 如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成(并且原因 R 被丢弃)。

当块中没有returntry,则finally执行return该块并使用该块中的finally

当块中有areturntry,可以认为该try块是突然结束的,但是根据JLS,该finally块仍然会在代码返回之前执行。

您还可以参考 JLS 的第 14.17 节来帮助理解 return 语句。

有趣的是,该部分底部的注释:

前面的描述说“尝试转移控制”,而不仅仅是“转移控制”,因为如果方法或构造函数中有任何 try 语句(第 14.20 节),其 try 块或 catch 子句包含 return 语句,那么这些的任何 finally 子句在将控制权转移到方法或构造函数的调用者之前,将按从内到外的顺序执行 try 语句。finally 子句的突然完成可能会中断由 return 语句启动的控制转移。

于 2013-10-23T05:12:47.940 回答
0

finally块后执行trycatch块。因此,如果您发表评论,那么如果没有异常发生return 40,它将返回值。try block这就是为什么return 10

如果发生异常而不是返回catch block20

于 2013-10-23T04:54:37.687 回答
0

这是finally 块的好读物。

finally 块总是在 try 块退出时执行。这样可以确保即使发生意外异常也会执行 finally 块。但 finally 不仅仅对异常处理有用——它允许程序员避免清理代码意外地被 return、continue 或 break 绕过。将清理代码放在 finally 块中始终是一个好习惯,即使没有预料到异常也是如此。

于 2013-10-23T04:55:02.577 回答