簡體   English   中英

用Java拋出檢查異常

[英]Throwing checked exception in Java

假設我正在設計一個用於存儲密碼的API。 根據Effective Java,使用throw子句顯示已檢查的異常是一個好主意,但是,通過具有拋出SQLException的throw子句(這是一個已檢查的異常),那么我將揭示API的基本實現細節,因此,我將稍后無法更改我的API的實現詳細信息。 引發檢查異常的優點之一是,使用API​​的程序員應能夠以自己選擇的方式處理異常。 我應該選擇這兩種方法中的哪一種,添加一個throw子句以顯示實現或將其隱藏或使用其他方法?

您的動機是正確的,因為沒有向類的用戶“泄漏” SQLException

您正在使用SQL的事實可以被視為實現細節。 您甚至可以稍后將SQL持久性換成一個內存中的持久性,並且此更改不應影響您的類的用戶。

如果您傾向於使用檢查的異常,則可以定義自己的異常類型(例如, PasswordStoreException僅作為示例名稱)。 您可以使用它包裝引發的原始異常,例如:

try {
   // do whatever
} catch (SQLException ex) {
   throw new PasswordStoreException(ex);
}
  1. 今天,API聲明已檢查的異常被認為是錯誤的設計。 如果您曾經使用過這樣的API,則應該已經知道原因。
  2. 在任何情況下,您的API都絕對不能拋出(更不用說聲明 )屬於其他API的異常。 如果這樣做,您將完全不相關的依賴項掛在客戶的背上。 該規則的唯一“例外”是JDK的標准例外,例如NPE,ISE等。

捕獲SQLException,並將其包裝到您自己的異常中:

try {
    // JDBC code
}
catch (SQLException e) {
    throw new MyException("Error persisting the secret", e); // choose a better name, of course
}

該異常是應檢查的異常還是運行時異常,取決於調用方對此的處理方式。 如果它是可恢復的(我認為不是這種情況),則應將其作為檢查異常。 如果它是不可恢復的(調用方只能顯示一條錯誤消息),那么它應該是運行時異常。

如果是檢查異常,則別無選擇。 異常必須在方法的throws子句中聲明。

嘗試這個..

調用fillInStackTrace()方法以重新初始化新創建的throwable中的堆棧跟蹤數據 嘗試訪問API時,將有助於掩蓋有關異常的信息

照原樣,將您自己的異常選中/取消選中總是一個好主意。 但是在此之前,請嘗試盡可能修復基礎異常。 我總是喜歡下面的方式,

try {
    // JDBC code
}
catch (SQLException e) {
    // try to solve the exception at API level
    bollean solvable = trySolveException(e);
    if (!solvable) {
        // Alert the admin, or log the error statement for further debugging.
        mailClient.sendMailToDBAdmin("Some issue storing password", e); 
        // or
        LOG.severe("some issue in storing password " + e.toString);
        throw MyException("A request/logstatement is logged on your behalf regarding the exception", e);
    }
    LOG.info("The exception is solved");
}
finally {
    // don't forget to free your resources - to avoid garbage and memory leaks, incase you have solved the issue in trySolveException(e).
}

所以,

1)您不會直接公開SRQException,但是會拋出自己的異常版本。

2)您嘗試解決該異常一次,如果沒有解決,則通過郵件或日志語句以某種方式發出警報。

3)最后,如果成功解決了異常,您就釋放了所有資源。

如果您使用新的Java7的try with resource close選項,則可以避免finally子句。

關於是否引發檢查或未檢查的異常,我將舉一個例子

1)說出像NPE這樣的異常-它們是程序錯誤,開發人員應更負責任地創建NullPointer。 您不希望您的代碼考慮到這樣的粗心大意的錯誤,而是嘗試使用try(NPE),catch(NPE)。 因此拋出未經檢查的異常。

2)另一方面,像SQL異常這樣的異常在極少數情況下會引起一些外部依賴性。 因此,最好拋出一個用戶定義的檢查異常。 用戶可以確定是否可以連接到備用SQL Server。

3)還有另一個例外條款,即程序無法繼續運行。 說出無限的回憶。 應該將它們作為錯誤拋出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM