Effective Java 第三版——75. 在详细信息中包含失败捕获信息
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. 在详细信息中包含失败捕获信息的更多相关文章
- Effective Java 第三版——46. 优先考虑流中无副作用的函数
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - Effective Java 第三版——16.在公共类中使用访问方法而不是公共属性
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - 《Effective Java 第三版》目录汇总
		
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
 - 《Effective Java 第三版》新条目介绍
		
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
 - Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - Effective Java 第三版——10. 重写equals方法时遵守通用约定
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - Effective Java 第三版——14.考虑实现Comparable接口
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 - Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
		
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
 
随机推荐
- 【官档整理】Visual Studio 2017 VS2017 中文离线安装包下载
			
[官档整理]Visual Studio 2017 VS2017 中文离线安装包下载 转 https://blog.csdn.net/fromfire2/article/details/81104648 ...
 - 使用Nginx+uwsgi在亚马逊云服务器上部署python+django项目完整版(二)——部署配置及相关知识
			
---恢复内容开始--- 一.前提: 1.django项目文件已放置在云服务器上,配置好运行环境,可正常运行 2.云服务器可正常连接 二.相关知识 1.python manage.py runserv ...
 - 大数据环境完全分布式搭建hbase-0.96.2-hadoop2
			
1.上传hbase安装包 2.解压 3.配置hbase集群,要修改3个文件 (首先zookeeper集群已经安装好了 并且启动 hadoop启动) 注意:要把hadoop的hdfs-site.xml和 ...
 - C#选择文件、选择文件夹、打开文件
			
1.选择文件用OpenDialog OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = true;//该值确定是否可以 ...
 - Java基础巩固——《Java核心技术基础·卷一:基础知识》
			
阅读记录追踪:前言部分 阅读前先看:简介.目录和勘误! Java编程语言是一种多用途.并发的.基于类的.面向对象的编程语言:编译时通常包括将持续转化成机器无关的字节码表示.运行时活动包括加载和链接执行 ...
 - 潭州课堂25班:Ph201805201 tornado 项目 第四课  增加用户注册登录(课堂笔记)
			
tornado 相关说明 在 handlers 中创建个 auth.py 用来做用户登录,在这文件中创建个类,并逐步完善 在 tornado 中创建 login.html 文件,是个登录页面 {% e ...
 - sweetalert的使用
			
1.swal()方法中的参数: 2.引入css与js,通过cdn加速服务 <link href="https://cdnjs.cloudflare.com/ajax/libs/swee ...
 - Jupyter Notebook 快捷键和技巧
			
Jupyter Notebook 有两种键盘输入模式. 编辑模式,允许你往单元中键入代码或文本,这时的单元框线是绿色的. 命令模式,键盘输入运行程序命令:这时的单元框线是蓝色. 命令模式 ...
 - Python Mongodb接口
			
Python Mongodb接口 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. 同时,MongoDB 是一个介于关系 ...
 - 最长递增子序列( LIS)
			
LIS LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求最长的上升序列,那 ...