首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 異常處理機制入門:try-catch-finally 核心語法與流程

     編輯:Java 相關知識

異常處理是 Java 程式健壯性的基石。本文從異常定義、分類體系、五大關鍵字(try/catch/throw/throws/finally)語法、執行流程到常見陷阱,為初學者建立清晰的異常處理認知框架。

一、什麼是異常?

異常:程式執行期間發生的非預期事件(錯誤、中斷正常流程)。Java 用物件封裝異常資訊,發生時建立異常物件並「拋出」(throw),呼叫鏈向上傳遞直到被「捕捉」(catch)或導致執行緒終止。

  • JVM 拋出:違反語言規範(NullPointerException)、超出執行環境限制(StackOverflowError)。
  • 手動拋出:throw new IllegalArgumentException("參數非法"),用於報告業務邏輯錯誤。

二、異常繼承體系速覽


java.lang.Throwable
├── java.lang.Error          // 嚴重錯誤,不可恢復(OOM, StackOverflow)
└── java.lang.Exception      // 應用層異常,可捕捉處理
    ├── java.lang.RuntimeException  // 非受檢異常(編譯器不強制處理)
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   └── IllegalArgumentException
    └── 其他 Exception 子類       // 受檢異常(必須 try-catch 或 throws)
        ├── IOException
        ├── SQLException
        └── ClassNotFoundException

三、五大關鍵字語法與標準模板


try {
    // 監控區塊:可能拋出異常的代碼
    riskyOperation();
} catch (ExceptionType1 e) {
    // 處理 ExceptionType1 及其子類
    handleType1(e);
} catch (ExceptionType2 e) {
    // 處理 ExceptionType2
    handleType2(e);
} finally {
    // 清理區塊:無論是否異常、是否 return,皆會執行(極少數例外:System.exit, 死循環)
    cleanupResources(); // 關閉流、釋放鎖、關閉連線
}

關鍵規則

  1. try 後必須跟至少一個 catch 或 finally。
  2. catch 子句按順序匹配,**子類異常必須寫在父類之前**,否則編譯錯誤(unreachable catch)。
  3. finally 即使在 catch 中 return 也會執行;但 System.exit(0) 或 JVM 崩潰則不執行。
  4. throw 用於方法內部主動拋出異常物件;throws 用於方法簽名聲明可能拋出的受檢異常。

四、執行流程圖解


正常情況:
try 區塊依序執行 → 跳過所有 catch → 執行 finally → 繼續後續代碼

異常情況(假設第 2 行拋出 IOException):
try 第 1 行 → 第 2 行拋出 → 跳過 try 剩餘 → 匹配 catch (IOException) → 執行該 catch → 執行 finally → 繼續後續

異常未捕捉:
try 拋出 Exception → 無匹配 catch → 執行 finally → 異常向上拋給呼叫者

五、常見陷阱與最佳實踐

1. finally 中的 return 覆蓋異常


public int test() {
    try { return 1; }
    finally { return 2; } // 方法回傳 2,原本的異常或 return 1 被吞沒!
}

鐵律:finally 區塊絕對不要使用 return/throw/break/continue。

2. 資源洩漏:舊式手動關閉


// 錯誤:若 read() 拋出異常,close() 不會執行
FileInputStream fis = new FileInputStream("a.txt");
try { fis.read(); } catch (IOException e) { }
fis.close();

3. Try-with-resources (Java 7+) 標準寫法


// 自動關閉實作 AutoCloseable 的資源,順序反向
try (FileInputStream fis = new FileInputStream("a.txt");
     BufferedInputStream bis = new BufferedInputStream(fis)) {
    bis.read();
} catch (IOException e) {
    log.error("讀取失敗", e);
}
// 編譯器自動生成 finally { bis.close(); fis.close(); }

4. 異常吞沒與堆疊追蹤丟失


// 錯誤:新異常未保留原始 cause
catch (SQLException e) { throw new RuntimeException("DB錯誤"); }

// 正確:保留因果鏈
catch (SQLException e) { throw new BizException("DB錯誤", e); }

5. 受檢 vs 非受檢選擇原則

  • 受檢異常:呼叫端合理預期能恢復(如檔案不存在 → 提示用戶重選)。
  • 非受檢異常:程式錯誤(Bug)、不可恢復系統故障、或架構層面統一處理(如 Spring @ControllerAdvice)。

六、多重 catch 與 Java 7+ 合併捕捉


// Java 7+ 多重捕捉(聯集類型)
try { ... }
catch (IOException | SQLException e) {
    log.error("IO/DB 錯誤", e);
    throw new DataAccessException(e);
}

結語

異常處理的核心是「失敗快速、資源不洩漏、堆疊可追蹤」。掌握 try-with-resources、正確使用 finally、保留因果鏈、合理選擇異常類型,能讓你的 Java 程式在異常情況下依然穩健可控。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved