Effective java笔记-第九章-异常

来源:互联网 发布:ace.min.js是什么 编辑:程序博客网 时间:2024/06/01 08:06

第57条:只针对异常的情况才使用异常

try{    int i = 0;    while(true){        range[i++].climb();    }catch(ArrayIndextOutOfBoundsException e){    }}
这段代码可以利用catch来终止无限循环,但这段代码有一下几个缺点:1.模糊了代码的意图2.把代码放在try-catch快中阻止本来可能要执行的某些特定优化3.如果出现了不相关的Bug,这个模式会掩盖这个Bug所以:异常应该只用于异常的情况下;他们永远不应该用于正常的控制流对API设计的启发:设计良好的API不应该强迫它的客户端为了正常的控制流而使用异常如果类具有“状态相关”的方法,也应该有个单独的“状态测试”方法。例如:Iterator接口有个“状态相关”的next方法,和相应的“状态测试”方法hasNext如果没有这个hasNext方法,客户端将被迫改用下面的做法:
try{    Iterator<Foo> i = collection.iterator();    while(true){        Foo foo = i.next()    }catch(NoSuchElementException e){    }}
另一种类似的做法是:如果"状态相关的"方法被调用时,该对象处于不适当的状态中,他就会返回一个可识别的值,如null。一些会影响这两种方法选择的因素:调用”状态测试“方法和调用"状态相关"方法之间状态是否会改变以及同步情况,”状态测试“方法和”状态相关“方法的重复度

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

三种throwable:受检的异常(checked exception),运行时异常(run-time exception),错误(error)异常选择原则:    1.对可恢复的情况使用受检异常    2.对编程错误使用运行时异常    3.最好不要在实现任何新的Error子类对于受检异常,提供一些辅助方法尤其重要

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

如果发现某个受检异常不必要(如根本恢复不过来),可以用这种重构方法:try{    obj.action(args);}catch(TheCheckedException e){    //Handle exceptional condition    ...}重构为if(obj.actionPermitted(args)){    obj.action(args);}else{    //Handle exceptional condition    ...}这种方法跟57条中的状态测试方法本质上是一样的,所以也有着同样的问题:    1.缺少外部同步的情况下被并发访问,会被外界改变状态    2.actionPermitted方法如果必须重复action的方法,性能就不高

第60条 优先使用标准的异常

IllegalArgumentException-->非null的参数值不正确IllegalStateException-->对于方法调用而言,对象状态不合适NullPointerException-->在禁止使用null的情况下参数值为nullIndexOutOfBoundsException-->下标参数值越界ConcurrentModificationException-->在禁止并发修改的情况下,检测到对象的并发修改UnsupportedOperationException-->对象不支持用户请求的方法

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

如果方法抛出的异常与它所执行的任务没有明显的联系,如方法传递由低层抽象抛出的异常会有两点缺点:    1.让人不知所错    2.如果高层的实现在后续的发行版发生改变,它所抛出的异常也可能跟着发生变化,从而破坏现有的客户端程序解决方法是异常转译:更高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常一种特殊的异常转译是异常链,如果低层的异常对于调试导致高层异常的问题非常有帮助,就可以使用异常链。异常链:低层的异常被传到高层的异常,高层的异常提供访问方法来获得低层的异常

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

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

第64条 努力使失败保持原子性

一般而言,失败的方法调用应该使对象保持在被调用之前的状态。具有这种属性的方法被称为具有失败原子性.这种原子性可以防止对象处在不一致的状态中.

第65条 不要忽略异常

不要用空的catch块
0 0
原创粉丝点击