记一道有意思的try-catch-finally的题

351 阅读1分钟

代码如下:

public int calculate() {

        int x = 1;

        try {
            System.out.println("A");
            return ++x;

        } catch (Exception e) {
            //System.out.println("D");
        } finally {
            System.out.println("B");
            ++x;
        }
        System.out.println("C");
        return x;
    }
    
# 代码展示

请问最终的输出结果是多少? 正确答案是

A
B
2

那么为什么不是

A
B
C
3

debug我们可以看到在try中进行return ++x后,x的值为2,直接进入到finally中,在finally中++x,x的值变成了3,再往下又回到了try中,如下图:

继续debug就会返回

A
B
2

为什么会产生这样的结果呢

官方解释

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

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


如果 try 语句里有 return,那么代码的行为如下: 
A,有返回值:就把返回值保存到局部变量中 
(执行”return ++x”,x=2,保存在局部变量) 
B,执行 jsr 指令跳到 finally 语句里执行 
(准备执行finally{…}代码块) 
C,执行完 finally 语句后,返回之前保存在局部变量表里的值 
(虽然执行”++x”后x=3,但是返回保存在局部变量中的x=2)