public static boolean test() {
try {
throw new Exception("Something error");
} catch (Exception e) {
System.out.println("Catch: " + e.getMessage());
return false; // 準備返回 false
} finally {
return true; // 直接返回 true,異常被吞噬,catch 的 return 失效
}
}
// 調用 test() 返回 true,控制台僅輸出 "Catch: Something error"
字節碼層面:finally 中的 return 會生成 jsr/ret 或內聯代碼,直接覆蓋操作數棧頂的返回值,導致異常對象未被傳播。
public static int demo() {
try {
return 1;
} finally {
return 2; // 覆蓋為 2
}
}
// 返回 2
public static int demo2() {
int x = 1;
try {
return x;
} finally {
x = 2; // 修改局部變量,不影響已壓棧的返回值 1
}
}
// 返回 1(基本類型/不可變對象引用值在 return 時刻已確定)
try {
// 1. 正常執行或拋出異常
} catch (Exception e) {
// 2. 匹配則進入,可 return/throw
} finally {
// 3. 無論上述如何(除 JVM 崩潰/System.exit),必執行
// 若這裡 return/throw,將覆蓋 try/catch 的返回/異常
}
// 4. 繼續後續代碼
AutoCloseable,無需手寫 finallypublic String readFirstLine(Path path) throws IOException {
try (BufferedReader br = Files.newBufferedReader(path)) { // 自動關閉
return br.readLine();
} // 隱式 finally:br.close(),異常傳播不受影響
}