2011-04-18 66 views
60

请参阅以下代码并解释输出行为。返回语句在catch中的行为,最后

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); 
    } 

} 

结果是返回瓦尔:10

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

catch块中的return语句会发生什么?

+0

的可能重复[为什么改变返回的变量在finally块不会改变返回值?](http://stackoverflow.com/questions/ 16030858 /为什么要改变返回变量在最后块不改变回报) – fglez 2013-04-30 07:32:21

+2

一个非常受欢迎的面试问题。 – 2014-06-29 20:09:12

回答

67

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

这就是为什么,经验法则 - 永远不会从finally返回。例如,Eclipse为该片段显示警告:“finally块不能正常完成”

49

finally总是执行(唯一的例外是System.exit())。你可以认为这种行为是这样的:

  1. ,则抛出异常
  2. 异常被捕获和返回值被设定为5
  3. 最后块被执行和返回值设置为10
  4. 的函数返回
+0

try/catch块的一般规则:1)永不返回finally块中的值。 2)避免在finally中抛出异常或捕捉黑色,因为它掩盖了原始异常。 – Matt 2012-08-08 04:36:09

+12

终于说总是执行是一件非常危险的事情。你真的不能依赖它被执行的关键任务操作。考虑一下像停电,jvm腐败/崩溃等等。我知道这听起来有点挑剔,但总是一句强烈的话,我想有时候我们会忘记我们生活在这样的灾难中的真实世界里发生。 – corsiKa 2013-02-15 18:26:40

3

finally块总是执行(如果执行该匹配尝试),所以该方法返回5如在catch块之前,它执行finally块并返回10.

17

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

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

如果对此类事情不确定,请回到您对底层系统的理解(最终转到汇编程序级别)。

funny sidenote

0

的最后部分将执行始终执行。例如如果你有任何东西要释放,或者注销某种东西,如果发生错误,那么去catch部分,最后会执行。

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

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

3

enter image description here

finally块总是得到,除非和直到System.exit()的说法是先在finally块来执行。

所以在上面的例子中,通过try语句引发Execution并捕获catch块。有返回语句所以在堆栈调用值最后被添加到finally块执行和最新的返回值被添加到堆栈顶部而返回值,堆栈返回最新值按堆栈行为“LAST先出”所以它会返回值