【问题标题】:How does this code works in java internal processing这段代码在java内部处理中是如何工作的
【发布时间】:2013-11-01 05:13:45
【问题描述】:

我知道即使代码抛出异常或成功完成,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;
            }
        }
    
    }

【问题讨论】:

标签: java exception-handling


【解决方案1】:

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

因此,当 finally 块中有 return 时,该函数返回 40,当 finally 块中没有返回时,函数返回 try 块中的值。


建议在finally 块中返回。

【讨论】:

  • 简洁、简短的描述。几乎完美,(并且得到了我的投票),但您可能希望将“到达 ...”的措辞更改为“就在 try 块中执行 return 之前...”。到达时只是有点模糊地表明它是在执行之前还是在执行期间。
  • @EdwinBuck 谢谢。更新以消除歧义。
【解决方案2】:

根据 Java 语言规范,Section §14.20.2

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

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

...

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

try 块中没有return 时,则执行finally 块并使用finally 块中的return

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

也可以参考JLS的Section §14.17来帮助理解return语句。

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

前面的描述说的是“试图转移控制权”,而不是 不仅仅是“转移控制”,因为如果有任何尝试语句 (§14.20) 在 try 阻塞或 catch 的方法或构造函数中 子句包含 return 语句,然后是任何 finally 子句 这些 try 语句将按顺序执行,最里面 最外层,在控制权转移到方法的调用者之前 或构造函数。 finally 子句的突然完成可能会破坏 由 return 语句启动的控制转移。

【讨论】:

    【解决方案3】:

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

    如果发生异常,则返回catch block 的值20

    【讨论】:

      【解决方案4】:

      这是finally block 的好读物。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-16
        • 2014-05-10
        • 1970-01-01
        • 2015-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多