Effective Java 第三版——75. 在詳細信息中包含失敗捕獲信息

Tips
書中的源代碼地址:https://github.com/jbloch/effective-java-3e-source-code
注意,書中的有些代碼裏方法是基於Java 9 API中的,因此JDK 最好下載 JDK 9以上的版本。java

Effective Java, Third Edition

75. 在詳細信息中包含失敗捕獲信息

當程序因爲未捕獲異常而失敗時,系統自動打印出異常的堆棧軌跡 。堆棧軌跡包含異常的字符串表示,這是調用其toString方法的結果。這一般包括異常的類名及其詳細信息。一般,這是程序員或網站可靠性工程師在調查軟件故障時所掌握的惟一信息。若是失敗不容易重現,則可能很難或不可能得到更多信息。所以,異常的toString方法返回儘量多的關於失敗緣由的信息是很是重要的。換句話說,異常的詳細信息應該捕獲失敗,以便後續分析。git

要捕獲失敗,異常的詳細消息應包含致使異常的全部參數和屬性的值。 例如,IndexOutOfBoundsException的詳細消息應包含下限,上限和不能在邊界之間的索引值。 這些信息告訴了不少關於失敗的信息。 三個值中的任何一個或所有均可能是錯誤的。 索引可能比下限小一或等於上限(「fencepost error」),或者它多是一個野值(wild value),過低或過高。 下限可能大於上限(嚴重的內部不變失敗)。 這些狀況中的每一種都指向一個不一樣的問題,若是你知道正在尋找什麼樣的錯誤,它將極大地幫助你進行診斷。程序員

有一個與安全敏感信息有關的警告。由於堆棧軌跡可能在診斷和修復軟件問題的過程當中被許多人看到,因此不要包括密碼、加密密鑰等詳細信息github

雖然在異常的詳細信息中包含全部相關數據很是重要,但一般不須要包含大量的不相關的信息。堆棧軌跡與文檔一塊兒分析,若是須要,再與源代碼一塊兒分析。它一般包含拋出異常的確切文件和行號,以及堆棧上全部其餘方法調用的文件和行號。冗長的描述失敗信息是多餘的;能夠經過閱讀文檔和源代碼來收集信息。編程

不該將異常的詳細消息與用戶級錯誤消息混淆,後者必須可以爲最終被用戶理解。 與用戶級錯誤消息不一樣,詳細消息主要是爲了程序員或網站可靠性工程師在分析故障時的緣由。 所以,信息內容遠比可讀性重要。 用戶級錯誤消息一般是本地化的,而異常詳細消息不多被本地化。安全

確保異常在其詳細消息中包含足夠的失敗捕獲信息的一種方法是,在其構造方法中,而不是字符串詳細消息中要求此信息。 而後能夠自動生成詳細消息中包括該信息。 例如,IndexOutOfBoundsException可能有一個以下所示的構造方法,而不是String構造方法:post

**
 * Constructs an IndexOutOfBoundsException.
 *
 * @param lowerBound the lowest legal index value
 * @param upperBound the highest legal index value plus one
 * @param index      the actual index value
 */

public IndexOutOfBoundsException(int lowerBound, int upperBound,
                                 int index) {
    // Generate a detail message that captures the failure
    super(String.format(
            "Lower bound: %d, Upper bound: %d, Index: %d",
            lowerBound, upperBound, index));
    // Save failure information for programmatic access
    this.lowerBound = lowerBound;
    this.upperBound = upperBound;
    this.index = index;
}

從Java 9開始,IndexOutOfBoundsException最終得到了一個接受int值index參數的構造方法,但遺憾的是它刪除了lowerBound和upperBound兩個參數。更廣泛地說,Java類庫並無大量使用這個習慣用法,可是強烈推薦使用它。它使程序員很容易拋出異常來捕獲失敗。事實上,它使程序員不想捕獲失敗都難!實際上,這個習慣用法將代碼集中在異常類中生成高質量的詳細信息,而不是要求該類的每一個使用者都冗餘地生成詳細信息。網站

如條目 70所示,異常可能適合爲其失敗捕獲信息(上例中的lowerBound,upperBound和index)提供訪問器方法。 在檢查異常上提供此類訪問器方法比未檢查異常更爲重要,由於故障捕獲信息可用於從故障中恢復。 程序員可能但願以編程方式訪問未檢查異常的細節,這種狀況不多見(儘管也是能夠想象的)。 可是,即便對於未檢查異常狀況,最好根據通常原則提供這些方法的訪問器(條目 12,第57頁)。this

相關文章
相關標籤/搜索