finally 塊在 try/catch 的 return 執行之後、返回值確定之後、實際返回給調用者之前執行。
public static int test1() {
int b = 20;
try { return b += 80; } // 返回值 100 已確定
finally { System.out.println("finally"); }
}
輸出:`try block → finally block → 100`。finally 在 return 後執行,但不影響返回值。
public static int test2() {
try { return 100; }
finally { return 200; } // 直接返回 200
}
輸出:`200`。finally return 會導致外層 return 成為不可達代碼(編譯錯誤需註釋)。
public static int test3() {
int b = 20;
try { return b += 80; } // 返回值 100 脫離 b
finally { b = 150; } // 修改 b 無效
}
輸出:`100`。返回值在 try return 時已壓棧,finally 修改局部變數不影響。
public static int test4() {
int b = 20;
try { b = b/0; return b; } // 不執行
catch { b += 15; return b; } // 返回值 35 確定
finally { b += 50; } // 不影響 35
}
輸出:`35`。catch return 同理,返回值確定後 finally 執行不影響。
public static int test5() {
try { throw new Exception(); }
catch { return 100; }
finally { return 200; }
}
輸出:`200`。
| 場景 | 返回值來源 | finally 能否修改返回值 |
|---|---|---|
| try return 正常 | try return 值 | 不能(值已壓棧) |
| catch return | catch return 值 | 不能 |
| finally 有 return | finally return 值 | 直接覆蓋 |
| 異常未捕獲 | 無(拋出) | 仍執行 |
理解「返回值確定 → finally 執行 → 實際返回」的順序,是寫正確資源釋放代碼(如關閉流、釋放鎖)的關鍵。
出處:bianceng.cn