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

相关文章
相关标签/搜索