24. return 的实际执行过程
public static int test() { int a = 10; return a;}用 javap -c 反编译:
0: bipush 10 // 把 10 压入操作数栈2: istore_0 // 弹出栈顶,存到局部变量表 slot 0(变量 a)3: iload_0 // 从 slot 0 加载值,压入操作数栈4: ireturn // 弹出栈顶值,返回给调用者可以看到 return a 对应两条指令:iload_0(加载值)和 ireturn(返回)
有 finally 时的字节码
public static int test() { int a = 10; try { return a; } finally { a = 20; }}字节码(简化):
0: bipush 10 // 压入 102: istore_0 // 存到 a (slot 0)
3: iload_0 // 加载 a 的值 (10)4: istore_1 // 暂存到 slot 1 ← 关键:保存返回值
5: bipush 20 // finally: 压入 207: istore_0 // finally: 存到 a (slot 0)
8: iload_1 // 加载暂存的值 (10)9: ireturn // 返回 10执行流程拆解
| 步骤 | 指令 | 操作数栈 | slot 0 (a) | slot 1 (暂存) |
|---|---|---|---|---|
| 1 | bipush 10 | [10] | - | - |
| 2 | istore_0 | [] | 10 | - |
| 3 | iload_0 | [10] | 10 | - |
| 4 | istore_1 | [] | 10 | 10 |
| 5 | bipush 20 | [20] | 10 | 10 |
| 6 | istore_0 | [] | 20 | 10 |
| 7 | iload_1 | [10] | 20 | 10 |
| 8 | ireturn | 返回 10 | - | - |
关键点
return a 实际上是:
iload_0 → 把 a 的值加载到栈顶istore_1 → 把栈顶值暂存起来(编译器插入的)... finally 代码 ...iload_1 → 加载暂存值ireturn → 返回编译器在遇到 try-finally 时,会自动插入暂存指令,确保 finally 执行后能返回正确的值。
所以你看到的 return a 这一行 Java 代码,实际对应了”加载 → 暂存 → finally → 加载暂存 → 返回”这一整套流程。