深入分析 try return finally之间执行顺序的问题

           前一段时间一直在参加各种公司的面试,面了很多家,也有几家自己觉得很不错的,准备5.1后从中挑一家准备入职了。职业生涯下一段的开始。在下一段工作开始前,有一段空闲时间。然后,就总结了以下那些奇奇怪怪的笔试题,想好好的分析下这类笔试题背后的运行原理。闲话不多说,直接上代码。其中有一道笔试题如下:

            深入分析 try return finally之间执行顺序的问题

请问,以上代码输出的是多少?

           我当时按照我所知道的原则————finally块总是会执行的去判断,模棱两可的回答了,返回的是2。后面回到房间,由于好奇,自己在机器上跑了下,发现其实输出的是 9 。 于是就更好奇了。有以下两个疑问:

            1 )  难道 try中的 return 语句没用执行 ?

            2 )或者是 try中的return 语句已经执行了,但是后面有finally,于是等待finally执行,然后在finally中返回了?

            带着这两个疑问,去查阅了相关资料。刚好近期自己在看《深入理解Java虚拟机》,以及研究字节码方面的内容。

           查阅Java语言规范得知,即使 try 中有 return 语句,在return 前,先回去执行 finally 里面的内容。如果 try 和 finally 中都有 return 的话, 那么是 先 执行 try 里面 return 后面的 语句(但是不return),然后再去执行finally中的return( 就是 return 这个操作最终是finally中返回的,try中的被忽略了)。

            我们可以通过以下这段代码,然后通过断点调试去验证以上结论:

深入分析 try return finally之间执行顺序的问题

上面这段代码输出的是 3。我们可以通过断点分析代码的执行过程:

       很清晰的能看到程序的执行过程是:

                1 ) 先 执行 15 行的 ++i ;( 然后这时候 并没有return)

                2 ) 再执行 19 行的 ++i,并 return 出去。

深入分析 try return finally之间执行顺序的问题

深入分析 try return finally之间执行顺序的问题

深入分析 try return finally之间执行顺序的问题

我们也可以通过字节码分析, try 和 finally 中的 ++i 都执行了:

( iinc 将指定int型变量增加指定值 如: i++,i--, i += 2 等 )

  iinc    0 ,1 将本地第一个变量 加 1

深入分析 try return finally之间执行顺序的问题

本来以为到这,就结束了。后面看到另外一篇帖子 你真的了解try{ return }finally{}中的return?  觉得也很好奇,看了作者解析的很到位,我在此就不做重复的劳动了,大家有兴趣,直接移步过去就OK了。



后记

    1 )  这段时间研究从字节码角度分析了一些问题,感觉有种透彻感。就像 李运华 说的,学一门语言呀,先学习下基本语法,再研究下细节和原理,然后再实践一下就能快速掌握。是的,最近就在 细节 与 原理之间穿行。推荐下 李运华的专访  以及 李运华的博客 

    2 ) 感谢 周老师 的 《深入理解Java虚拟机》,不管是自己,还是在网上看到的好多博客,都发现对这本书的引用很多。

最后,李运华最近在极客时间开了 架构 系列的专栏哦,扫下面的码可以购买:

深入分析 try return finally之间执行顺序的问题