返回语句在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()
)。 你可以这样思考这个行为:
- 抛出exception
- exception被捕获并且返回值被设置为5
- 最后块被执行,返回值被设置为10
- 函数返回
如果您记住虚拟机的低级布局,这是一个简单的问题。
- 返回值是由catch代码堆栈。
- 之后,执行finally代码并覆盖堆栈上的值。
- 然后,该方法返回最新值(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();}
它不应该用来返回任何东西。 你可以在外面使用。