finally 區塊在 try 或 catch 中的 return 執行前必定執行。若 finally 中也有 return,會覆蓋外部返回值;若 finally 修改了局部變量,不影響已壓棧的返回值 (基本類型/引用地址)。
public int test1() {
int i = 10;
try { return i += 10; } // 返回值 20 壓入棧
finally { System.out.println(i); } // 輸出 20
} // 返回 20
public int test2() {
int i = 10;
try { return i += 10; }
finally { return 50; } // 覆蓋返回 50
}
public int test3() {
int i = 10;
try { return i; } // 返回值 10 壓入棧
finally { i = 50; } // 修改局部變量,不影響已壓棧的 10
} // 返回 10
字節碼層面:try 中 return 先將值存入局部變量表槽位,再跳轉到 finally;finally 結束後從槽位加載返回。若 finally 有 return,直接從 finally 返回,跳過槽位加載。最佳實踐:避免在 finally 中使用 return 或拋出異常,僅用於資源清理。