| 維度 | throw | throws |
| 位置 | 方法體內 | 方法簽名 |
| 動作 | 拋出具體異常對象 | 聲明可能拋出的異常類型 |
| 語法 | throw new Exception() | throws Exception1, Exception2 |
| 單獨使用 | 否(需 try-catch 或 throws 配合) | 可(拋給調用者處理) |
| 本質 | 主動拋出動作 | 被動聲明契約 |
異常傳遞鏈路示例
void doA() throws Exception1, Exception3 {
try {
// 可能產生 Exception1,2,3
} catch (Exception1 e) {
throw e; // 重新拋給調用者
} catch (Exception2 e) {
System.out.println("內部處理"); // 內部消化,不向外拋
}
if (a != b) throw new Exception3("自定義"); // 邏輯檢查主動拋
}
Exception1:捕獲後重拋 → 調用者處理
Exception2:內部處理完畢 → 不聲明 throws
Exception3:業務邏輯主動拋出 → 聲明 throws,調用者處理
檢查型異常 vs 非檢查型異常
- 檢查型:
Exception 子類(非 RuntimeException),**編譯器強制** try-catch 或 throws
- 非檢查型:
Error、RuntimeException 及子類,**編譯器不強制**,通常為編程錯誤/系統級故障
最佳實踐原則
- 具體捕獲:捕獲具體異常類,避免
catch (Exception e) 吞噬錯誤信息
- 異常鏈:重拋時保留原始堆棧:
throw new BizException("業務失敗", e)
- 資源管理:
try-with-resources (Java 7+) 自動關閉 AutoCloseable 資源
- 不作流控:異常用於**錯誤處理**,不用於正常業務流程控制
- 文檔化:Javadoc
@throws 說明拋出條件
- 日志記錄:邊界處捕獲並記錄完整堆棧,內部層級可只拋不記
自定義異常設計
public class BizException extends RuntimeException {
private final int code;
public BizException(int code, String msg, Throwable cause) {
super(msg, cause);
this.code = code;
}
}
- 業務異常繼承
RuntimeException(非檢查型),減少樣板代碼
- 攜帶錯誤碼、國際化鍵、原始原因
- 全局異常處理器統一轉換為標準錯誤響應
總結
異常處理核心:**邊界捕獲、內部拋出、資源自動清理、錯誤碼標準化**。掌握五大關鍵字語義、catch 順序、finally 執行邊界、throws/throw 差異、檢查型與非檢查型策略,編寫健壯、可維護的 Java 代碼。
- 上一篇文章: Java 容器核心體系與 API 詳解
- 下一篇文章: Java Swing 鍵盤繪圖實戰:鍵盤事件驅動面板繪製圖形
Copyright ©
程式碼之家 All Rights Reserved