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

Java 自訂異常類別完整指南:從繼承 Exception 到豐富異常資訊

     編輯:Java 相關知識

在 Java 開發中,雖然內建的異常類別已能涵蓋大多數常見錯誤情境,但實際專案往往需要表達特定業務邏輯的錯誤狀態。此時建立自訂異常類別便顯得尤為重要。本文將詳細說明如何透過繼承 Exception 類別來建立屬於自己的異常體系,並示範如何為異常添加建構子、資料欄位與存取方法,使其攜帶更豐富的診斷資訊。

為什麼需要自訂異常?

Java 的標準異常階層雖然完善,但無法預知所有程式庫或應用程式特有的錯誤類型。當你開發一個供他人使用的類別庫時,拋出標準異常往往缺乏業務語意,導致呼叫端難以精準捕獲並處理特定錯誤。自訂異常能讓你:

  • 定義具備業務含義的異常類型(如 InsufficientBalanceException、InvalidOrderStateException)
  • 攜帶額外的錯誤上下文資訊(錯誤碼、相關物件狀態、時間戳等)
  • 建立清晰的異常階層,方便呼叫端依錯誤性質進行分級處理

基本做法:繼承 Exception 類別

建立自訂異常的核心在於 extends Exception。這表示新類別「是一個」Exception,擁有其所有功能,並可擴充屬於自己的行為。最簡單的自訂異常只需提供兩個標準建構子:

public class MyException extends Exception {
    public MyException() {}
    public MyException(String msg) {
        super(msg);  // 明確呼叫父類別帶字串參數的建構子
    }
}

關鍵點解析:

  • 無參建構子:若不顯式定義,編譯器會自動產生並呼叫 super();但慣例上仍建議明確寫出。
  • 帶訊息建構子:透過 super(msg) 將錯誤訊息傳給父類別,讓 getMessage() 能正常運作。

實戰範例:拋出與捕獲自訂異常

以下完整程式展示如何在方法中拋出 MyException,並在 main 中捕獲處理:

public class Inheriting {
    public static void f() throws MyException {
        System.out.println("Throwing MyException from f()");
        throw new MyException();
    }

    public static void g() throws MyException {
        System.out.println("Throwing MyException from g()");
        throw new MyException("Originated in g()");
    }

    public static void main(String[] args) {
        try { f(); } catch (MyException e) { e.printStackTrace(); }
        try { g(); } catch (MyException e) { e.printStackTrace(); }
    }
}

執行輸出:

Throwing MyException from f()
MyException
    at Inheriting.f(Inheriting.java:16)
    at Inheriting.main(Inheriting.java:24)
Throwing MyException from g()
MyException: Originated in g()
    at Inheriting.g(Inheriting.java:20)
    at Inheriting.main(Inheriting.java:29)

觀察可知:無訊息建構子拋出的異常堆疊追蹤缺乏詳細說明,而帶訊息版本則清晰標示錯誤來源。

進階擴充:為異常添加資料與行為

異常本質上也是物件,因此可以像一般類別一樣擁有欄位、方法與多載建構子。以下範例加入整數欄位 i 及對應的存取方法:

public class MyException2 extends Exception {
    private int i;  // 額外的錯誤碼或狀態值

    public MyException2() {}
    public MyException2(String msg) { super(msg); }
    public MyException2(String msg, int x) {
        super(msg);
        i = x;
    }
    public int val() { return i; }  // 提供讀取額外資料的方法
}

使用方式:

public static void h() throws MyException2 {
    throw new MyException2("Originated in h()", 47);
}

// 捕獲時可取得額外資訊
try { h(); } 
catch (MyException2 e) { 
    e.printStackTrace(); 
    System.out.println("e.val() = " + e.val());  // 輸出 47
}

極簡異常:只繼承、不加碼

有時只需一個標記性質的異常類型,完全依賴編譯器自動產生的預設建構子即可:

class SimpleException extends Exception { }

此時無 String 參數建構子,但對於單純用於型別判斷的情境已足夠。

設計建議與最佳實務

  1. 語意命名:類別名以 Exception 結尾,清楚表達錯誤性質。
  2. 提供標準建構子組合:至少包含無參、帶訊息、帶訊息與原因(Throwable cause)三種,符合 Java 異常鏈慣例。
  3. 不可變性:異常物件建立後不應修改內部狀態,所有欄位建議宣告為 final。
  4. 文件化:在 JavaDoc 中說明何時拋出、攜帶何種資訊、呼叫端應如何處理。

掌握自訂異常的建立與擴充技巧,能讓你的程式碼錯誤處理更具表達力、可維護性與專業度。

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