其实return和finally的执行顺序问题非常简单,你只有看看代码的指令就清楚咯

简介: 看看代码的指令就清楚咯


image.png

  最近在整理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,就会创建一个栈帧(存储局部变量表,操作数栈等信息)进入虚拟机栈。每一个方法从调用到执行完毕,就是一个栈帧从虚拟机栈中入栈到出栈的过程。对应的栈帧情况为

image.png

ldc:将int,float或者String类型常量从常量池推送至栈顶。

astore:将栈顶引用型类型数据存入指定本地变量。

aload:将制定的引用类型变量推送至栈顶

查看关键的指令为:

image.png

还有一种情况需要注意,如果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 对应的栈帧位置
        }
    }
}

image.png

  通过指令我们可以看到在finally中的return关键字的指令返回的就是finally中的局部变量的信息,可以理解为finally中的return会覆盖掉try块中的return逻辑。




相关文章
|
1月前
|
Python
如何在Python中处理异常?给出try-except-finally语句的例子。
在Python中,异常处理通过try-except-finally结构实现。try包含可能抛出异常的代码,except捕获特定异常并处理,finally则确保无论是否发生异常,某些代码(如资源释放)总会执行。
15 1
|
1月前
|
Python
使用try-except-finally语句的例子。
使用try-except-finally语句的例子。
|
1月前
|
设计模式 消息中间件 前端开发
finally中的代码一定会执行吗?
finally中的代码一定会执行吗?
464 0
|
7月前
|
Oracle Java 关系型数据库
try-catch必须放在循环体外吗
try-catch必须放在循环体外吗
因为一道题,我把 try-catch-finally 的细节都整理了一遍(1500字)
原因:return i++; 在内部是可以分为三步,① int tmp = i; ② i += 1; ③ return tmp;
72 0
因为一道题,我把 try-catch-finally 的细节都整理了一遍(1500字)
|
Web App开发 前端开发 JavaScript
重学前端 20 # try里面放return,finally还会执行吗?
重学前端 20 # try里面放return,finally还会执行吗?
116 0
重学前端 20 # try里面放return,finally还会执行吗?
|
应用服务中间件 Apache nginx
Yii框架中的'enablePrettyUrl' => true, 这段代码是干什么的?底层原理是什么?为什么这样写?
Yii框架中的'enablePrettyUrl' => true, 这段代码是干什么的?底层原理是什么?为什么这样写?
125 0
线程的创建等待及退出 代码源码举例
线程的创建等待及退出 代码源码举例
53 0
while、do...while、死循环 演示 demo
while、do...while、死循环 演示 demo
97 0
while、do...while、死循环 演示 demo
|
Dart JavaScript
[Flutter]足够入门的Dart语言系列之流程控制语句:中断和异常(continue/break、try...catch)
循环的执行是通过循环条件来控制的,但是,有时我们想要通过额外的条件判断,来决定是否中断执行,或者中断本次循环而继续执行下次及之后的循环;此外,我们需要对于异常情况的处理...
374 0
[Flutter]足够入门的Dart语言系列之流程控制语句:中断和异常(continue/break、try...catch)