public int test() {
int i = 0;
try {
i++;
return i; // 此處 i=1
} finally {
i--; // i 變為 0
}
}
// 輸出:1 而非 0
i++ → i=1。return i:先計算表達式值 (1),存入操作數棧/局部變量表的返回值槽位,然後準備跳轉至 finally。finally 塊:i-- → i=0(修改的是局部變量槽位,不影響已保存的返回值)。
4. finally 正常完成,方法返回之前保存的值 1。
finally 對變量的修改不影響返回值。finally 中若再次執行 return,會覆蓋之前的返回值。finally 中拋出異常會吞噬 try/catch 的返回值/異常,拋出新異常。// 編譯器視角的偽代碼
int test() {
int i = 0;
int returnValue; // 隱式返回值槽
try {
i++;
returnValue = i; // 保存返回值
// 隱式 goto finally
} finally {
i--;
}
return returnValue; // 真正返回
}
| 代碼變體 | 輸出 | 說明 |
|---|---|---|
finally { i--; return i; } | 0 | finally 中 return 覆蓋 |
try { return i++; } finally { i--; } | 1 | 後置 ++ 先取值後增,返回值仍為 1 |
try { throw new Exception(); } finally { return 99; } | 99 | finally return 吞噬異常 |
try { System.exit(0); } finally { ... } | 不執行 finally | JVM 直接退出 |
try-with-resources (Java 7+) 自動管理,無需手寫 finally。int result = i++; ... finally { i--; } return result;理解返回值確定時刻,避免「以為 finally 能改返回值」的直覺陷阱,寫出可預測的健壯代碼。