捕获和最终返回语句的行为


71

请参见以下代码,并解释输出行为。

public class MyFinalTest {

    public int doMethod(){
        try{
            throw new Exception();
        }
        catch(Exception ex){
            return 5;
        }
        finally{
            return 10;
        }
    }

    public static void main(String[] args) {

        MyFinalTest testEx = new MyFinalTest();
        int rVal = testEx.doMethod();
        System.out.println("The return Val : "+rVal);
    }

}

结果是返回Val:10。

Eclipse显示警告:finally block does not complete normally

catch块中的return语句会怎样?



6
一个非常受欢迎的面试问题。
giannis christofakis 2014年

Answers:


74

它被中的1覆盖finally,因为finally在所有其他操作之后执行。

这就是为什么,经验法则-永不从回归finally。例如,Eclipse显示了该代码段的警告:“最终阻止无法正常完成”


51

finally始终执行(唯一的例外是System.exit())。您可以通过以下方式考虑此行为:

  1. 引发异常
  2. 捕获异常并将返回值设置为5
  3. 最终执行块并将返回值设置为10
  4. 函数返回

try / catch块的一般规则:1)切勿在finally块中返回任何值。2)避免在finally中引发异常或捕获黑色,因为它会掩盖原始异常。
马特

13
说最后总是被执行是非常危险的事情。您确实不能依靠执行它来执行关键任务操作。考虑一下诸如停电,jvm损坏/崩溃等问题。我知道这听起来有些挑剔,但始终是一个很强的词,我想有时候我们会忘记我们生活在现实世界中,在这种世界中,灾难确实如此发生。
corsiKa

19

如果您还记得虚拟机的底层布局,这是一个简单的问题。

  1. 返回值由catch代码放入堆栈。
  2. 然后,执行最终代码并覆盖堆栈上的值。
  3. 然后,该方法返回最新值(10),供调用者使用。

如果不确定这样的事情,请回到对底层系统的理解(最终进入汇编程序级别)。

有趣的旁注


4

在此处输入图片说明

除非并且直到在finally块中首先出现System.exit()语句,否则finally块始终被执行。

因此,在上面的示例中,try语句引发了Exection并在catch块中获取了catch。有一个返回值为5的return语句,因此在堆栈调用中,将在稍后执行finally块时添加值5,并在返回值时在堆栈顶部添加最新的返回值,根据堆栈行为“ LAST IN FIRST OUT”,堆栈返回最新值,因此它将返回值为10。


3

finally块始终执行(如果执行了匹配的try),因此在该方法像该catch块一样返回5之前,它会执行该finally块并返回10。


0

最后部分将始终执行。例如,如果您有任何要释放的东西,或注销某样东西,如果发生错误,则转到捕获部分,否则最终将执行。

Session session //  opened some session 
try 
{
 // some error 
}
catch { log.error }
finally 
{ session.logout();}

它不应该用于返回任何东西。您可以在外面使用。


0

简而言之,无论try还是catch块中存在return,我们都可以说finally块在return语句中起主导作用

最终总是在该用例中占主导地位。

public static int m1() {
    try {
        return 100;
    } 
    catch(Exception e)
    {
        return 101;
    }
    finally {
        return 102;
    }
}

输出-102


0

最终块将始终执行(唯一的例外是它在它之前的任何地方都遇到System.exit()),因此在最终块返回之前,简单地将5替换(覆盖)为10

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.