您的位置:首页 > 其它

以字节码角度解释return和finally的执行顺序?

2016-03-01 13:44 281 查看
前言(Preface):

关于return和finally的执行顺序,算是一个“老梗”了吧,大家众说纷纭,相信很多人已经看过很多版本的解释。但有些人可能只是通过简单的代码测试得出来的结论,没有从根本上解释这个问题。Java编译器把代码编译成字节码,我们通过反汇编字节码,查看字节码指令顺序,能根本地解释return和finally的执行先后问题。

问题(What):

return和finally的执行顺序是怎么样的(无异常抛出的情况下)?

解答(How):

求出返回值--->另外开辟空间,存放返回值的副本--->执行finally--->return返回值的副本

分析(Why):

程序代码段如下(无异常抛出)

public static void main(String[] args) {
System.out.println(test02());
}

public static String test02(){
String t = null;
try {
t = "try";
return t;
} catch (Exception e) {
}finally{
t = "finnally";
}
return t;
}

执行该段代码,输出:try



使用javap -c Test反汇编该段代码得到对应test02的字节码指令:



下面对字节码作出分析:

1. 执行finally之前,会执行aload_0取出try,再执行astore_3(第5-6行),astore_3的目的是复制返回值(try, 常量或者引用)的一个副本,即变量3

2. 接着执行finally,改变 t 的值,此时t 的值是finally(7-9行)

3. 最后load出变量3,再将其返回(10-11行)

结论(Conclusion):

执行finally之前,求出返回值,比如return “str1”+ "str2",接着程序会另外开辟空间复制返回值的一个副本,再执行finally,等到执行完finally,再将副本return。

思考(More):

如果返回值是自定义类,会是什么情况呢?情况跟上面是一样的,只不过副本变成了一个对象引用。详细在此就不作分析了。

另外,在下只是分享自己学习后的观点看法,若有疏忽或错误的地方,还望指教

未完待续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: