返回语句在catch和finally中的行为

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

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语句会发生什么?

finally被这个人覆盖了,因为finally被执行了一切。

这就是为什么,一个经验法则 – 从来没有从finally回来 。 例如,Eclipse对这个片段显示一个警告:“finally块不能正常完成”

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

  1. 抛出exception
  2. exception被捕获并且返回值被设置为5
  3. 最后块被执行,返回值被设置为10
  4. 函数返回

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

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

如果不确定这样的事情,回到你对底层系统的理解(最终转到汇编层面)。

( 有趣的旁注 )

finally块总是被执行(如果匹配try被执行),所以在catch块中返回5之前​​,它会执行finally块并返回10。

在这里输入图像描述

finally块总是得到执行,除非和直到System.exit()语句在finally块中第一次。

所以在上面的例子中,try语句被try语句抛出并被catch语句catch。 有值为5的返回语句,所以在堆栈调用值5获得最后添加块后执行和最新的返回值被添加到堆栈的顶部,而返回值,堆栈返回最新值按照堆栈行为“最后在先”这样它将返回值为10。

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

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

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