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

Java 父子類異常處理鐵律:構造器與方法覆寫的異常聲明規則

     編輯:Java 相關知識

核心結論先行

子類構造器:throws 必須 包含 父類構造器異常(父 ⊆ 子)
子類方法:throws 必須 子集 於父類方法異常(子 ⊆ 父)

規則一:構造器異常必須「向上兼容」

原因

  1. 子類實例化必先調用父類構造器(隱式/顯式 super())
  2. super() 必須置於首行,無法被 try-catch 包裹
  3. 父類構造器拋出的異常,子類構造器必須聲明拋出(或其父類異常),否則編譯錯誤

代碼驗證

class BaseEx extends Exception {}
class SubEx extends BaseEx {}

class Parent {
    Parent() throws BaseEx {}
    Parent(int x) throws SubEx {}
}

class Child extends Parent {
    // ✅ 合法:拋出父類異常
    Child() throws BaseEx { super(); }
    
    // ✅ 合法:拋出父類異常父類
    Child(int x) throws Exception { super(x); }
    
    // ❌ 非法:未聲明父類異常
    // Child() { super(); } // Compile Error
    
    // ❌ 非法:拋出無關異常
    // Child() throws IOException { super(); } // Compile Error
}

規則二:方法覆寫異常必須「向下兼容」

原因:里氏替換原則(LSP)

父類引用指向子類對象時,調用者按父類異常契約編程。若子類拋出父類未聲明的異常,調用者無法捕獲 → 破壞多態安全。

代碼驗證

interface Service {
    void doWork() throws IOException;
}

class BaseService {
    void doWork() throws FileNotFoundException {} // 子類異常
}

class Impl extends BaseService implements Service {
    // ✅ 合法:不拋異常
    @Override void doWork() {}
    
    // ✅ 合法:拋出父類異常子集
    @Override void doWork() throws FileNotFoundException {}
    
    // ❌ 非法:拋出父類未聲明異常
    // @Override void doWork() throws SQLException {} // Compile Error
    
    // ❌ 非法:實現接口拋出更寬泛異常
    // @Override void doWork() throws Exception {} // Compile Error
}

特殊場景:多重繼承衝突


interface A { void m() throws IOException; }
interface B { void m() throws SQLException; }

class C implements A, B {
    // 必須同時滿足兩個接口:throws 子集於 IOException ∩ SQLException = 無
    // 唯一解:不拋檢查異常
    @Override public void m() {} 
}

運行時異常特權

RuntimeException 及其子類 不受聲明約束:

  • 父類未聲明,子類可拋出 NullPointerException
  • 子類聲明 throws RuntimeException 合法但無意義(文檔用)

最佳實踐

  1. 檢查異常:嚴格遵循「子 ⊆ 父」,設計時在父類聲明盡可能具體的異常體系
  2. 運行時異常:不寫 throws,用 Javadoc @throws 說明
  3. 構造器:盡量不拋檢查異常,改用靜態工廠方法或初始化方法
  4. 異常鏈:throw new ChildException("msg", parentCause) 保留根因

總結

Java 異常聲明規則本質是契約繼承:構造器「向上傳遞責任」,方法「向下收斂風險」。理解 LSP 與 super() 調用機制,即可靈活應對所有覆寫場景。

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