我发现了一个有趣的现象:finally中“改不了”返回值!

2023-08-28 17:46:04 浏览数 (2)

嗨!今天我要跟大家分享一个有关 Java 编程的有趣现象,就是在 `finally` 块中无法改变返回值。别担心,我会以轻松的方式来解释这个问题,并给出具体的字节码指令分析,让大家一起开心地学习!

首先,让我们回顾一下 `finally` 的作用。在 Java 中,`finally` 是一个用于定义必须执行的代码块,无论是否发生异常。这使得它成为处理资源释放和清理的理想地方。但是,有一点需要注意:`finally` 块中的任何改变都不会影响 `try` 或 `catch` 块中的返回值。

那么问题来了,为什么 `finally` 块中无法改变返回值呢?让我们深入探索一下字节码指令!

首先,我们来看一个简单的代码示例:

代码语言:javascript复制
public static int getValue() {
    int value = 10;
    try {
        return value;
    } finally {
        value = 20;
    }
}

我们期望这个方法返回值为 20,但事实并非如此。现在,让我们来看看这段代码的字节码指令:

代码语言:javascript复制
0: bipush        10       // 加载常量 10 到操作数栈上
2: istore_0               // 存储操作数栈上的值到本地变量 value
3: iload_0                // 从本地变量 value 中加载值到操作数栈上
4: ireturn                // 返回操作数栈上的值
5: astore_1               // 异常处理开始,将异常对象存储到本地变量
6: bipush        20       // 加载常量 20 到操作数栈上
8: istore_0               // 存储操作数栈上的值到本地变量 value
9: aload_1                // 将异常对象加载到操作数栈上
10: athrow                // 抛出异常

可以看到在第四行程序直接通过ireturn就把操作数栈上的10就返回了,之后才去执行了finally里的代码。 `finally` 块中的新值赋给了本地变量 `value`,但这对于返回值并没有任何影响。因为 `finally` 块是在返回指令执行之后才执行的,所以无论怎么修改本地变量 `value`,返回值都已经被确定下来了。

所以,即使 `finally` 块中的代码改变了 `value` 的值,也不会影响方法的返回值~

0 人点赞