未被捕獲的異常拋出後,後續代碼永不執行(編譯期報錯「unreachable statement」);被 try-catch 捕獲且 catch 塊不拋出新異常,後續代碼正常執行。
public void test1() throws Exception {
throw new Exception("參數錯誤");
System.out.println("異常後"); // 編譯錯誤:unreachable statement
}
原因:編譯器確定該行不可達,直接阻止編譯。
public void test2() {
try {
throw new Exception("參數錯誤");
} catch (Exception e) {
e.printStackTrace(); // 僅記錄,不拋出
}
System.out.println("異常後"); // 正常輸出
}
public void test3() throws Exception {
if (true) {
throw new Exception("參數錯誤");
}
System.out.println("異常後"); // 編譯通過,但運行時永不執行
}
區別:編譯器無法確定 if 條件恒真,故允許編譯;JVM 運行時異常拋出導致方法終止。
| 異常類型 | 代表 | 處理要求 | 不處理後果 |
|---|---|---|---|
| 受檢異常 (Checked) | IOException、SQLException、ParseException | 強制 try-catch 或 throws 聲明 | 編譯錯誤 |
| 非受檢異常 (Unchecked/Runtime) | NullPointerException、IndexOutOfBoundsException、IllegalArgumentException | 可選處理 | 運行時拋出,JVM 默認打印堆棧並終止線程 |
| Error | OutOfMemoryError、StackOverflowError | 不應捕獲處理 | JVM 級別嚴重錯誤,通常不可恢復 |
public void add(int index, Element element) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("索引越界: " + index); // 無需聲明 throws
}
// 後續代碼正常執行...
}
public User findById(Long id) {
try {
return jdbcTemplate.queryForObject(sql, mapper, id);
} catch (EmptyResultDataAccessException e) {
throw new BusinessException("用戶不存在: " + id, e); // 運行時異常
} catch (DataAccessException e) {
throw new SystemException("數據庫訪問失敗", e); // 運行時異常
}
}
public void processFile(String path) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(path));
// 處理邏輯
} catch (IOException e) {
throw new RuntimeException("文件讀取失敗", e);
} finally {
if (reader != null) {
try { reader.close(); } catch (IOException ignored) {}
}
}
// 此處代碼正常執行(若無異常拋出)
}
發生異常
│
├─ 能在當前層級有意義處理? ──是──► try-catch 處理,記錄日誌,嘗試恢復或返回默認值
│
└─ 否
│
├─ 是受檢異常? ──是──► 包裝為非受檢異常拋出 (throws RuntimeException)
│
└─ 否 (已是運行時異常) ──► 直接拋出,由全局異常處理器統一處理