Tips

书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code

注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

75. 在详细信息中包含失败捕获信息

当程序由于未捕获异常而失败时,系统自动打印出异常的堆栈轨迹 。堆栈轨迹包含异常的字符串表示,这是调用其toString方法的结果。这通常包括异常的类名及其详细信息。通常,这是程序员或网站可靠性工程师在调查软件故障时所掌握的唯一信息。如果失败不容易重现,则可能很难或不可能获得更多信息。因此,异常的toString方法返回尽可能多的关于失败原因的信息是非常重要的。换句话说,异常的详细信息应该捕获失败,以便后续分析。

要捕获失败,异常的详细消息应包含导致异常的所有参数和属性的值。 例如,IndexOutOfBoundsException的详细消息应包含下限,上限和不能在边界之间的索引值。 这些信息告诉了很多关于失败的信息。 三个值中的任何一个或全部都可能是错误的。 索引可能比下限小一或等于上限(“fencepost error”),或者它可能是一个野值(wild value),太低或太高。 下限可能大于上限(严重的内部不变失败)。 这些情况中的每一种都指向一个不同的问题,如果你知道正在寻找什么样的错误,它将极大地帮助你进行诊断。

有一个与安全敏感信息有关的警告。因为堆栈轨迹可能在诊断和修复软件问题的过程中被许多人看到,所以不要包括密码、加密密钥等详细信息

虽然在异常的详细信息中包含所有相关数据非常重要,但通常不需要包含大量的不相关的信息。堆栈轨迹与文档一起分析,如果需要,再与源代码一起分析。它通常包含抛出异常的确切文件和行号,以及堆栈上所有其他方法调用的文件和行号。冗长的描述失败信息是多余的;可以通过阅读文档和源代码来收集信息。

不应将异常的详细消息与用户级错误消息混淆,后者必须能够为最终被用户理解。 与用户级错误消息不同,详细消息主要是为了程序员或网站可靠性工程师在分析故障时的原因。 因此,信息内容远比可读性重要。 用户级错误消息通常是本地化的,而异常详细消息很少被本地化。

确保异常在其详细消息中包含足够的失败捕获信息的一种方法是,在其构造方法中,而不是字符串详细消息中要求此信息。 然后可以自动生成详细消息中包括该信息。 例如,IndexOutOfBoundsException可能有一个如下所示的构造方法,而不是String构造方法:

**
* 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页)。

Effective Java 第三版——75. 在详细信息中包含失败捕获信息的更多相关文章

  1. Effective Java 第三版——46. 优先考虑流中无副作用的函数

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. Effective Java 第三版——16.在公共类中使用访问方法而不是公共属性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  4. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  5. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——14.考虑实现Comparable接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. 使用Chrome浏览器设置XX-net的方法

        以下介绍使用Chrome浏览器设置XX-net的方法 1.下载并安装谷歌浏览器. 2.打开https://github.com/XX-net/XX-Net/blob/master/code/d ...

  2. Mysql数据库报错:Cannot add or update a child row: a foreign key constraint fails(添加多对多关系)

    #创建班级表 class Classes(models.Model): title = models.CharField(max_length=32) n=models.ManyToManyField ...

  3. 从小白到区块链工程师:第一阶段:Go语言的控制台输入和输出(3)

    六,Print系列的函数输出 1:Println 打印换行.Print控制台打印,lnline 一行,打印数据后自动换一行显示.下面显示在控制台打印出不同的类型. 打印输出结果后,会自动换一行.打印结 ...

  4. 表达式语言引擎:Apache Commons JEXL 2.1 发布

    http://www.linuxde.net/2011/12/4348.html Commons JEXL 2.1 发布了,该版本和 2.0.1 是二进制兼容的,但源码不兼容,因为新增了两个接口: o ...

  5. SPOJ COT3.Combat on a tree(博弈论 Trie合并)

    题目链接 \(Description\) 给定一棵\(n\)个点的树,每个点是黑色或白色.两个人轮流操作,每次可以选一个白色的点,将它到根节点路径上的所有点染黑.不能操作的人输,求先手是否能赢.如果能 ...

  6. 英语口语练习系列-C13-聚会

    词汇 音频 1. apartment [əˈpɑ:tmənt] n. 公寓 a big / small apartment 一个大的/小的公寓 in an apartment 在公寓 2. arm [ ...

  7. set_include_path和get_include_path用法详解

    首先set_include_path这个函数呢,是在脚本里动态地对PHP.ini中include_path进行修改的.而这个include_path呢,它可以针对下面的include和require的 ...

  8. 什么是C++

    1.到底什么是C++ C++是一门面向对象的程序设计语言. 关键词:程序设计语言,面向对象 程序设计语言是用来书写计算机程序的语言,更形象的说,程序设计语言是用来和计算机“交流的语言.” 面向对象(o ...

  9. Flask特殊装饰器

    @app.errorhandler():重定义错误返回信息 @app.errorhandler(404) #监听多少写多少 def error404(message): return f"你 ...

  10. Centos 7 安装配置

    修改网卡 最小化安装没有安装vim,暂时使用vi 进入到network-scripts 目录 [root@node1 ~]# cd /etc/sysconfig/network-scripts/ [r ...