《Effective Java》第9章 异常

充分发挥异常的优点,可以提高程序的可读性,可靠性和可维护性,如果使用不当,它们也会带来负面影响。

1. 只针对异常的情况才使用异常 【Item 57】
1) 顾名思义,异常应该只用于异常的情况下,它们永远不应该用于正常的控制流
2) 设计良好的API不应该强迫它的客户端为了正常的控制流而使用异常
2. 对可恢复的情况使用受检异常,对编程错误使用运行时异常 【Item 58】
1) Java程序语言设计了三种可抛出的结构:
a. 受检的异常(checked exception),可恢复情形
b. 运行时异常(run-time exception),不可恢复
c. 错误(error),不可恢复
2) 三种抛出结构使用的原则是如果期望调用者能够适当地恢复,对于这种情况就应该使用受检的异常,受检的异常需要客户端强制进行try-catch处理
3) 如果程序抛出未受检的异常或者错误,往往就属于不可恢复的情形,继续执行下去有害无益
4) 用运行时异常来表明编程错误,大多数运行时异常都表示提前违例,提前违例是指API的客户没有遵守API的规范建立的约定
5) 错误往往被JVM保留用于表示资源不足,约束失败,或者其他使程序无法继续执行的条件
6) 你实现的所有未受检的抛出结构都应该是RuntimeException的子类
7) 异常也是完全意义上的对象,可以在它上面定义任意的方法,这些方法的主要用途是为捕获异常的代码提供额外的信息,特别是关于引发这个异常条件的信息
8) 受检异常往往指明了可恢复的条件
3. 避免不必要地使用受检异常 【Item 59】
1) 如果正确的使用API并不能阻止这种异常条件的产生,并且一旦产生异常,使用API的程序员可以立即采取有用的动作,这种负担就被人为是正当的
2)因为受检异常要求API的客户必须try-catch做恢复处理,因此给程序员带来一些负担,所以尽量在必要的时候再使用
3) 如果某种合理的特殊情况下在某个类中处理异常,直接往上抛,不需要为有可能有受检异常抛出的API做try-catch
4. 优先使用标准的异常 【Item 60】
1) 重用现有异常的好处:
a. 使你的API更加易于学习和使用,因为它与程序员已经熟悉的习惯用法是一致的
b. 对于用到这些API的程序而言,它们的解读性会更好,疑问它们不会出现很对程序员不熟悉的异常
c. 异常类越少,意味着内存印迹(footprint)越小,装载这些类的时间开销也越少
2) 所有错误的方法调用都可以被归结为非法参数或者非法状态
5. 抛出与抽象相对应的异常 【Item 61】
1) 更高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常,这叫做异常转译,转译时同时记录低层异常的原因,有助于问题的分析
2) 这个转译之后的异常trace会有caused by链,打印出转译链便于上层理解以及分析
6. 每个方法抛出的异常都要有文档 【Item 62】
1) 始终要单独地声明受检的异常,并且利用javadoc的@throws标记,准确地记录下抛出每个异常的条件。
2) 受检的异常会在类或方法声明上明确有throws子句,未受检异常则不需要,这也是区分受检异常和未受检异常的重要标识
3) 使用javadoc的@throws标签记录下一个方法可能抛出的每个未受检异常,但是不要使用throws关键字将未受检的异常包含在方法的声明中,否则其变成了受检的异常
4) 如果在一个类中的许多方法中出于同样的原因而抛出同一个异常,在该类的文档注释中对这个异常建立文档,这是可以接受的,而不是为每个方法单独建立文档
5) 要为每个受检异常提供单独的throws子句,不要为未受检的异常提供throws子句
7. 在细节消息中包含能捕获失败的信息 【Item 63】
1) 为了捕获失败,异常的细节信息应该包含所有“对该异常有贡献”的参数和域的值,这对分析问题非常有帮助
2) 信息的内容比可理解性要重要得多,关键信息打印即可
3) 在异常的构造器而不是字符串细节信息中引入这些异常发生的关键原因信息
4) 为异常的“失败捕获”信息提供一些访问方法是合适的,提供这些方法对受检异常比未受检异常更为重要,为恢复方式提供必要的信息
8. 努力使失败保持原子性 【Item 64】
1) 一般而言,失败的方法调用应该使该对象保持在被调用之前的状态,具有这种属性的方法被成为具有失败原子性,也就是方法调用失败之后对象的状态不受本方法失败的影响
2) 获得失败原子性常见方法:
A. 设计一个不可变对象,失败原子性显而易见
B. 对于可变对象而言,获得失败原子性的方法:
a. 在执行操作之前检查参数的有效性
b. 调整计算处理过程的顺序,使得任何可能会失败的计算部分都在对象状态被修改之前发生
c. 编写一段恢复代码,类似于数据库回滚操作,在异常发生后恢复原状
d. 在对象的一份临时拷贝上操作,当操作完成之后再调用临时拷贝中的结果代替对象的内容
3) 作为方法规范的一部分,产生任何异常都应该让对象保持在该方法调用之前的状态,如果违反了这条规则,API文档就应该清楚的指明对象将处于什么样的状态
9. 不要忽略异常 【Item 65】
1) 空的catch块会使异常达不到应有的目的,一般不建议这么处理
2) 如果确定该异常不需要处理,用空的catch块代替,至少在空的catch块中用注释解释为什么可以这么做,提升代码的可读性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值