异常(八)

以下为我在《Effective Java》中留下的读书笔记,对一些重要的知识点提取出了摘要. 

57、只针对异常的情况才使用异常

使用标准模式,因为现代的JVM实现可能会将它们优化.

异常只用于异常的情况下,它们永远都不应该用于正常的控制流.

设计良好的API不应该强迫它的客户端为了正常的控制流而使用异常.

“状态测试方法” 与 "可识别的返回值" 两种做法的选择.

58、对可恢复的情况使用受检异常,对编程错误使用运行时异常

三种可抛出结构:受检异常、运行时异常和错误

如果期望调用者能够适当地恢复,对于这种情况就应该使用受检异常.

用运行时异常来表明编程错误 (RuntimeException)

异常也是完全意义上的对象,可以在上面定义任意的方法.这些方法的主要用途是为捕获异常的代码而提供额外的信息,特别是关于引发这个异常条件的信息.例如,假设因为用户没有储存足够数量的钱,他企图在一个收费电话上进行呼叫就会失败,于是抛出受检的异常.这个异常应该提供一个访问方法,以便允许客户查询所缺的费用金额.

59、避免不必要地使用受检的异常

受检异常会对程序员造成负担.如果正确地使用API并不能阻止这种异常条件的产生,并且一旦产生异常,使用API的程序员可以立即采取有用的动作,这种负担就被认为是正当的.除非这两个条件都成立,否则更适合使用未受检的异常.

添加 状态测试方法 以此把受检的异常变成未受检的异常.

60、优先使用标准的异常

所有错误的方法调用都可以被归结为非法参数或者非法状态
IllegalArgumentException 非法的参数异常
IllegalStateException 例如,在某个对象被正确地初始化之前,调用者就企图使用这个对象.

NullPointerException
IndexOutOfBoundsException     

ConcurrentModificationException     如果一个对象被设计为专用于单线程或者与外部同步机制配合使用,一旦发现它正在或已经被并发地修改,就可以抛出此异常.
UnsupportedOperationException     如果接口的具体实现没有实现该接口所定义的一个或多个可选操作,它就可以使用这个异常



61、抛出与抽象相对应的异常

异常转译  更高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常.

异常链   大多数标准异常都有支持链的构造器,对于没有支持链的异常,可以利用Throwable的initCause方法设置原因.

如果无法避免低层异常,次选方案是将高层方法的调用者与低层的问题隔离开来.可以用某种适当的记录机制(如java.util.logging)将异常记录下来.

62、每个方法抛出的异常都要有文档

方法声明受检异常,不声明未受检异常.
@throws 记录下所有受检异常和未受检异常.

63、在细节消息中包含能捕获失败的信息

为了捕获失败,异常的细节信息应该包含所有"对该异常有贡献"的参数和域的值.

异常的细节信息不应该与“用户层次的错误消息”混为一谈.前者注重内容,后者注重可理解性.

64、努力使失败保持原子性

保持失败原子性的方法:     设计一个不可变的对象
                                        在执行操作之前检查参数的有效性
                                        编写一段恢复代码(回滚)
                                        在对象的一份临时拷贝上执行操作

65、不要忽略异常

不应该有空的catch块. 至少,catch块也应该包含一条说明,解释为什么可以忽略这个异常.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值