Java 將「運行時問題」封裝為對象,所有異常類繼承自 Throwable,具備 可拋性:可被 throw (拋對象) 與 throws (聲明拋類) 操作。
Throwable
├── Error // JVM 級嚴重錯誤,不可恢復 (OOM, StackOverflow)
└── Exception // 應用級異常,可捕獲處理
├── RuntimeException // 運行時異常 (非受檢),編譯器不強制處理
│ ├── NullPointerException
│ ├── IllegalArgumentException
│ └── IndexOutOfBoundsException
└── 受檢異常 // 編譯期強制 try/catch 或 throws
├── IOException
├── SQLException
├── ClassNotFoundException
└── 自定義業務異常
| 關鍵字 | 位置 | 作用 | 異常類型 |
|---|---|---|---|
throw | 方法體內 | 拋出異常對象 | 單個 |
throws | 方法簽名 | 聲明拋出異常類 | 多個,逗號分隔 |
// 1. 完整模式:try-catch-finally
try {
// 高風險代碼
} catch (IOException e) {
// 處理邏輯
} finally {
// 必執行邏輯:關流、釋放鎖、清理資源
// 注意:System.exit(0) 會跳過 finally
}
// 2. 僅捕獲:try-catch
try { ... } catch (Exception e) { ... }
// 3. 僅清理:try-finally (Java 7+ 建議用 try-with-resources)
try (InputStream in = new FileInputStream("a.txt")) {
// 使用 in
} // 自動調用 in.close()
// 業務異常基類:受檢異常,強制調用者感知
public class BusinessException extends Exception {
private final int errorCode;
public BusinessException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() { return errorCode; }
}
// 具體業務異常:語義化命名
public class InsufficientBalanceException extends BusinessException {
public InsufficientBalanceException(String msg) { super(1001, msg); }
}
public class UserNotFoundException extends BusinessException {
public UserNotFoundException(String msg) { super(1002, msg); }
}
// 運行時異常基類:系統級/編程錯誤
public class SystemException extends RuntimeException {
public SystemException(String msg, Throwable cause) { super(msg, cause); }
}
Exception,系統異常 extends RuntimeException。super(message, cause) 保留原始原因鏈。@throws 條件與處理建議。catch (IOException e) 而非 catch (Exception e),避免吞噬非預期異常。throws 到 Controller 再統一處理 (除非統一錯誤碼轉換)。catch (Exception e) { } 絕對禁止,至少 log.error("", e)。try-with-resources 或 finally。throw new BusinessException(..., e) 而非 throw new BusinessException(...)。try { map.get(key); } catch { return default; } 應改用 map.getOrDefault()。// 矩形構造器:參數校驗拋運行時異常 (編程錯誤)
public class Rectangle implements Shape {
private final int len, wid;
public Rectangle(int len, int wid) {
if (len <= 0 || wid <= 0)
throw new IllegalArgumentException("矩形邊長必須 > 0");
this.len = len; this.wid = wid;
}
public void getArea() { System.out.println(len * wid); }
}
// 圓構造器:同理
public class Circle implements Shape {
private final int r;
public Circle(int r) {
if (r <= 0) throw new IllegalArgumentException("半徑必須 > 0");
this.r = r;
}
public void getArea() { System.out.println(Math.PI * r * r); }
}
// 調用方:無需 try-catch,讓運行時異常冒泡到全局異常處理器
public class Test {
public static void main(String[] args) {
new Circle(-8).getArea(); // 直接拋出 IllegalArgumentException
System.out.println("over"); // 不會執行
}
}
Java 異常機制的核心價值在於 強制錯誤顯性化:受檢異常強制 API 使用者面對可能失敗的操作,運行時異常暴露編程邏輯缺陷。掌握 異常分類選擇、自定義異常設計、try-with-resources 資源管理、全局異常處理器統一響應,是編寫健壯、可維護 Java 系統的必修課。