Effective Java(第三版) 学习笔记 - 第十章 异常 Rule69~Rule77
作者:互联网
目录
Rule70 对可恢复的情况使用受检异常,对编程错误使用运行时异常
Rule69 只针对异常的情况才使用异常
看了这篇之后,总结起来就一句话就可以概括了:不要把异常用于正常的控制流中,异常的初衷只是用于不正常的情形。
Rule70 对可恢复的情况使用受检异常,对编程错误使用运行时异常
所有的异常全部继承于Throwable,然后主要分三类
- 受检异常(Checked Exception):Exception下面所有非RuntimeException的异常。不是程序本身的错误,只是外部因素如文件读写异常、数据库异常,为了保障程序的健壮性,必须要捕获。
- 运行异常(Runtime Exception):Exception下面RuntimeException及其子类。程序本身抛出的异常,是程序是否严谨导致的,如果不主动捕获,则会被jvm处理。
- 错误(Error):底层和硬件有关的错误,无法捕获,捕获了也没有用。
如果需要自定义异常,期望调用者能够适当地恢复,对于这种情况就应该用受检异常。编程错误用运行时异常。一般Error及其子类,不需要我们去新定义,也不建议这样做。
什么叫适当地恢复,我的理解是基础的就像那种重试机制一样,并不是程序错误,有可能是其他原因,例如网络、内存资源不足等等。但是问题是能否恢复的界定并不是那么清晰,如果开发者觉得有一种情况可能允许恢复,建议用受检异常;否则应该用运行时异常。如果不确定能否恢复、建议用运行异常。
Rule71 避免不必要的使用受检异常
上一条中提到,如果不确定能否恢复建议用受检异常。但是受检异常过多也是一种负担,因为不管是catch住之后自行处理,还是直接throw都需要调用方的开发者显示的去处理。而且如果是在Java8的环境下,Stream中无法使用抛出受检异常的方法。
把自己当做是调用方,思考下如果自己调用时遇到了这个受检异常发生。自己能做些什么处理,如果只能catch之后出日志,然后中断程序;或者直接往上一级throw该异常,那么可能这个异常就不太适合用受检异常了。
Rule72 优先使用标准异常
与之前讲过的优先使用标准函数方法的内容一样,没什么好多说的。
Rule73 抛出与抽象对应的异常
简单来形容的话就是,不同的层次负责处理各自层级的异常。可以通过设置cause形成异常链。
try {
...
} catch (LowerLevelException cause) {
throw new HighLevelException(cause);
}
Rule74 每个方法抛出的所有异常都要建立文档
这个也没啥好说的,文档的重要性之前篇幅里面不少内容都提到过。
Rule75 在细节消息中包含失败 - 捕获信息
往往再出现异常,并希望能够根据异常信息分析问题原因时,最不喜欢看到的就是只打印的异常的名字。因为往往不容易分析原因,最好在异常的细节信息里面包含,必要的参数和域的值,以帮助我们可以定位问题原因或者再现问题。
但是需要注意的是,请不要直接打印客户的密码、密钥、卡号这种敏感信息。日志中的脱敏还是必要的。
Rule76 努力使失败保持原子性
因为有些异常,我们希望通过重试机制也好,其他的手段也好进行恢复。如果这个时候,程序运行到一半,抛出了异常,但是改变了原先存储的数据、状态等。那么这个时候等于数据源头被污染了。就像我们提交数据库会使用事务一样的原理。
常见的三种方法保持失败原子性:
- 调整处理顺序,将可能会失败的计算部分,在改变对象状态之前进行处理,提前检查发现。
- 提前拷贝一份数据备份,用于失败之后可以保持原样。
- 编写恢复代码,由它拦截失败,并且回滚到之前的状态。
Rule77 不要忽略异常
请不要catch异常之后,然后什么也不处理也不做,既不往上跑出,也不打印日志等。这样就等于将异常改成了正常的程序流程。关键事后也不好发现分析。
本文技术菜鸟个人学习使用,如有不正欢迎指出修正。xuweijsnj
标签:Java,Effective,受检,抛出,捕获,Rule69,恢复,使用,异常 来源: https://blog.csdn.net/weixin_44453385/article/details/118943516