专栏首页赵俊的Java专栏关于 Java finally 执行顺序 -- 修改版

关于 Java finally 执行顺序 -- 修改版

前言

之前写了一篇 关于 try-catch-finally 执行顺序 的文章,但是写的有些繁琐了,这里重新写一下。

题目

class Test {
    public int aaa() {
        int x = 1;

        try {
            return ++x;
        } catch (Exception e) {

        } finally {
            ++x;
        }
        return x;
    }

    public static void main(String[] args) {
        Test t = new Test();
        int y = t.aaa();
        System.out.println(y);
    }
}

我第一次看到这个题,得出了几个问题:

  • 如果在 try 语句块里有 return 语句,那么 finally 还会执行吗?
  • 如果执行那应该是怎样的执行过程呢?

首先这道题的运行结果是 2,可能跟你想的不一样吧,别急,下面我会慢慢解释的。

在学习 Java 基础的时候,老师就讲过,try-catch-finally 中的 finally 语句块一定会被执行,那么我们来 debug 一下:

初始状态:

此时运行到了 return ++x; 但还没执行该语句,目前 x 的值为 1.

这时发现跳到了 finally 语句块中,且 return ++x++ 操作已经执行,但没有进行 reutrn,目前 x 的值为 2:

执行完 finally 语句块中的 ++x 操作后,又回到了 return 中,此时 x 的值为 3:

但根据最后的运行结果,我们发现其实真正 reutrn 的是 2,那么如何解释这一点呢?

其实在 官方的 JVM 规范 中对这一部分有说明:

If the try clause executes a return, the compiled code does the following:

  1. Saves the return value (if any) in a local variable.
  2. Executes a jsr to the code for the finally clause.
  3. Upon return from the finally clause, returns the value saved in the local variable.

简单翻译如下:

如果 try 语句里有 return,那么代码的行为如下:

  1. 如果有返回值,就把返回值保存到局部变量中
  2. 执行 jsr 指令跳到 finally 语句里执行
  3. 执行完 finally 语句后,返回之前保存在局部变量表里的值

看完这个应该就能理解为什么返回的是 2 了,

但要注意的是:

  • 如果在 finally 语句块中也使用了 return 语句,那么会忽略 try 中的 return 语句,而执行 finally 中的 return。
  • 如果 try 中 return 的是引用数据类型,那么 finally 中的操作可能会影响最终的 return 值,因为对于引用数据类型,暂存到局部变量里的是它的地址值。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 由一道 Java finally 执行顺序的题引发的思考

    一份执着✘
  • Hadoop 伪分布式环境搭建

    一份执着✘
  • 爬楼梯

    一份执着✘
  • 你真的了解try{ return }finally{}中的return?

    The finally block always executes when the try block exits. This ensures that th...

    一觉睡到小时候
  • 你真的了解try{ return }finally{}中的return?

    刚看到这个问题后。突然发现基础不够扎实,居然来第一个都答不出来。。。(不知道还有木有和我也一样也回答不出以上的问题的? 如果有请在评论里告诉我一声,让我知道,我...

    用户1655470
  • Java关键字 Finally执行与break, continue, return等关键字的关系

    长文短总结: 在程序没有在执行到finally之前异常退出的情况下,finally是一定执行的,即在finally之前的return语句将在finally执行...

    老白
  • Java finally语句到底是在return之前还是之后执行?

    网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正...

    bear_fish
  • 【Android】如何知道某个Activity是否在前台?

    Gavin-ZYX
  • UiAutomator源码学习(1)-- UiDevice

    UiDevice提供对设备状态信息的访问。 也可以使用此类来模拟设备上的用户操作,例如按键盘或按Home和Menu按钮。UiDevice类的完整源码 UiDev...

    yuanyuan
  • Python finally的用法

    try语句有一个可选finally子句,用于定义在所有情况下都必须执行的finally操作

    于小勇

扫码关注云+社区

领取腾讯云代金券