方法宣告中的 throws 子句

Java 檢查的異常機制要求程式設計師宣告某些方法可以丟擲指定的已檢查異常。這是使用 throws 子句完成的。例如:

public class OddNumberException extends Exception { // a checked exception
}

public void checkEven(int number) throws OddNumberException {
    if (number % 2 != 0) {
        throw new OddNumberException();
    }
}

throws OddNumberException 宣告對 checkEven 的呼叫可能會丟擲 OddNumberException 型別的異常。

throws 子句可以宣告型別列表,並且可以包括未經檢查的異常以及已檢查的異常。

public void checkEven(Double number) 
        throws OddNumberException, ArithmeticException {
    if (!Double.isFinite(number)) {
        throw new ArithmeticException("INF or NaN");
    } else if (number % 2 != 0) {
        throw new OddNumberException();
    }
}

將未經檢查的異常宣告為丟擲的重點是什麼?

方法宣告中的 throws 子句有兩個用途:

  1. 它告訴編譯器丟擲了哪些異常,以便編譯器可以將未捕獲(已檢查)的異常報告為錯誤。

  2. 它告訴程式設計師正在編寫呼叫該方法的程式碼,以期望有什麼異常。為此,它經常使感官在 throws 列表中包含未經檢查的異常。

注意:生成 API 文件時,javadoc 工具也使用 throws 列表,並通過典型的 IDE懸停文字方法提示。

丟擲和方法重寫

throws 子句構成方法簽名的一部分,用於方法重寫。可以使用與重寫方法或子集丟擲的相同的已檢查異常集宣告覆蓋方法。但是,覆蓋方法無法新增額外的已檢查異常。例如:

@Override
public void checkEven(int number) throws NullPointerException // OK—NullPointerException is an unchecked exception
    ...

@Override
public void checkEven(Double number) throws OddNumberException // OK—identical to the superclass
    ...

class PrimeNumberException extends OddNumberException {}
class NonEvenNumberException extends OddNumberException {}

@Override
public void checkEven(int number) throws PrimeNumberException, NonEvenNumberException // OK—these are both subclasses

@Override
public void checkEven(Double number) throws IOExcepion         // ERROR

這個規則的原因是,如果一個 overriden 方法可以丟擲一個被覆蓋的方法無法丟擲的已檢查異常,那麼這將破壞型別的可替代性。