// 電腦異常基類
class ComputerException extends Exception {
public ComputerException(String msg) { super(msg); }
}
// 具體異常
class BlueScreenException extends ComputerException {
public BlueScreenException(String msg) { super(msg); }
}
class SmokeException extends ComputerException {
public SmokeException(String msg) { super(msg); }
}
// 老師業務異常
class NoPlanException extends Exception {
public NoPlanException(String msg) { super(msg); }
}
class Computer {
private int state = 3; // 2=藍屏, 3=冒煙
public void run() throws BlueScreenException, SmokeException {
if (state == 2) throw new BlueScreenException("電腦藍屏了");
if (state == 3) throw new SmokeException("電腦冒煙了");
System.out.println("電腦運行正常");
}
public void restart() { System.out.println("電腦重啟中..."); }
}
class Teacher {
private Computer computer = new Computer();
public void teach() throws NoPlanException {
try {
computer.run();
} catch (BlueScreenException e) {
// 可恢復異常:本地處理,不向上拋出
computer.restart();
System.out.println("藍屏已恢復,繼續上課");
} catch (SmokeException e) {
// 不可恢復異常:包裝業務語義向上拋出
throw new NoPlanException("上課無法繼續,原因:" + e.getMessage());
}
System.out.println("老師正在上課...");
}
}
public class ExceptionDemo {
public static void main(String[] args) {
Teacher t = new Teacher();
try {
t.teach();
} catch (NoPlanException e) {
System.out.println("主程序捕獲:" + e); // 輸出: NoPlanException: 上課無法繼續,原因:電腦冒煙了
}
}
}
| 模式 | 代碼體現 | 適用場景 |
|---|---|---|
| 捕獲並處理 | catch (BlueScreenException) { restart(); } | 異常可本地恢復,調用方無感知 |
| 捕獲轉換拋出 | catch (SmokeException e) { throw new NoPlanException(...); } | 底層異常無業務語義,需轉為業務異常 |
| 異常鏈保留 | new NoPlanException(msg, e) (Java 1.4+) | 保留原始堆棧,便於排查根因 |
| finally 清理資源 | try { ... } finally { close(); } | IO、鎖、連接必釋放 |
| 多異常合並捕獲 (Java 7+) | catch (BlueScreenException | SmokeException e) { ... } | 同邏輯處理多種異常 |
| try-with-resources (Java 7+) | try (Resource r = ...) { ... } | 自動關閉實現 AutoCloseable 的資源 |
catch (Exception e) { } 絕對禁止,至少 log.errorif (user == null) 代替 try { user.getName() } catch (NPE)@ControllerAdvice、Servlet error-page 統一返回友好錯誤// ❌ 異常控制流程
try { int i = list.get(100); } catch (IndexOutOfBoundsException e) { ... }
// ❌ 吞噬異常
try { risky(); } catch (Exception ignored) {}
// ❌ 過度包裝
throw new MyException("Error", e); // 又在上層包裝 MyException2 → 堆棧膨脹
// ✅ 正確
if (list.size() > 100) { ... }
try { risky(); } catch (SpecificException e) { log.error(e); throw new BusinessException(e); }
異常處理核心三原則:具體捕獲、語義轉換、資源保證釋放。將「電腦冒煙」轉為「課程無法繼續」,體現了異常翻譯思想:底層技術異常 → 業務語義異常。掌握 try-catch-finally、try-with-resources、異常鏈、自定義異常體系,即可編寫健壯、可維護的 Java 代碼。