其实return和finally的执行顺序问题非常简单,你只有看看代码的指令就清楚咯
Posted 波波烤鸭
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了其实return和finally的执行顺序问题非常简单,你只有看看代码的指令就清楚咯相关的知识,希望对你有一定的参考价值。
最近在整理Java常见的面试题,刚好整理到return和finally的执行顺序问题,这个很多小伙伴比较困惑,所以波波老师就通过指令带大家彻底弄清楚下
return和finally的顺序问题
分析如下的代码程序,给出输出结果,并给出原因
public class Demo02 {
public static void main(String[] args) {
Demo02 demo02 = new Demo02();
System.out.println(demo02.getName("bobo"));
}
public String getName(String name){
String res = "";
try {
res = name;
return res;
}finally {
res = "波波烤鸭";
}
}
}
输出的结果是:bobo
原因:通过指令分析我们可以发现在 return 代码执行的时候会将局部变量保存在 栈帧的顶部,然后在finally中修改的还是原来的栈帧位置的局部变量,最终返回的信息还是栈帧顶部的变量,所以finally代码块在return关键字之后会执行,但是不会改变栈帧顶部的信息。
指令分析:
首先我们要清楚在jvm中,每个线程都具有自己的虚拟机栈。当执行方法时,如上面的getName,就会创建一个栈帧(存储局部变量表,操作数栈等信息)进入虚拟机栈。每一个方法从调用到执行完毕,就是一个栈帧从虚拟机栈中入栈到出栈的过程。对应的栈帧情况为
ldc:将int,float或者String类型常量从常量池推送至栈顶。
astore:将栈顶引用型类型数据存入指定本地变量。
aload:将制定的引用类型变量推送至栈顶
查看关键的指令为:
还有一种情况需要注意,如果finally和try块中都有return关键字会怎么样呢?
public class Demo02 {
public static void main(String[] args) {
Demo02 demo02 = new Demo02();
System.out.println(demo02.getName("bobo"));
}
public String getName(String name){
String res = "";
try {
res = name;
return res;
}finally {
res = "波波烤鸭";
return res; // 指令中返回的就不是栈帧顶部的数据了 而是 res 对应的栈帧位置
}
}
}
通过指令我们可以看到在finally中的return关键字的指令返回的就是finally中的局部变量的信息,可以理解为finally中的return会覆盖掉try块中的return逻辑。
深入JVM指令分析return和finally的执行顺序问题
以上是关于其实return和finally的执行顺序问题非常简单,你只有看看代码的指令就清楚咯的主要内容,如果未能解决你的问题,请参考以下文章
return与finally的执行顺序的影响(skycto JEEditor)