您的位置:首页 > Web前端

《Effective Java》——异常

2015-07-26 11:18 295 查看

只针对异常情况才使用异常

异常设计的初衷就是针对程序的不正常情形所使用的,不要使用异常来控制程序的执行流程

对可恢复的情况使用受检异常,对编程错误使用非受检异常

Java设计了三种可以抛出的结构

checked exception

runtim exception

error

error一般情况下,约定俗称有虚拟机使用,表示资源不足等错误

对可恢复的情况使用受检异常,对编程错误使用非受检异常

避免不必要的使用checked exception

使用checked exception会给客户端程序员带来很大的负担,只有满足如下两个条件,才应该使用checked exception

即使正确调用该api此种情况也可能发生

对于异常的发生,程序员可以立即采取有用的动作

否则,应该使用runtime exception

优先使用标准的异常

重用现有的异常,有三个好处

使你的api易于学习和使用

对于使用api的程序来说,可读性会更好

异常类越少,装载时的开销也越小

常用的异常有如下几个

IllegalArgumentException

IllegalStateException

NullPointerException

IndexOutOfBoundException

ConcurrentModificationException

UnsupportedOperationException

抛出与抽象相对应的异常

当方法要传递底层实现抛出的异常时,要进行异常转译,不要使底层实现的异常污染了上层api

例如

catch(IOException e){
throw new ServiceException(e);
}


通常有两种转译方式,一种是直接异常的转译,一种是异常链的转译

上面的例子就是异常链的转译,调用方可以通过异常获得更底层的异常,方便排查问题,直接转译就是不传递异常链,例如

catch(IOException e){
throw new ServiceException("io exception");
}


以上只是针对一定要传递底层异常情况下的处理方法,对于底层的方法,首选方案是处理掉底层异常,不将异常的影响传递到上层去,一般有两条途径来实现

对参数进行检查,避免调用底层方法发现异常

绕开异常,将异常记录下来,不传播出去

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

为checked exception和unchecked exception都建立文档说明,但是不要在方法声明中标记unchecked exception

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

要记录下产生该异常的各种原因,最好能使异常自身记录下产生问题的原因,例如在异常的构造函数中包含一些特别的字段,就像在IndexOutOfBoundsException中可以有如下构造方法

public IndexOutOfBoundsException(int lowerBound, int upperBound, int index){
...


努力使失败保持原子性

失败的方法调用应该使对象保持在被调用之前的状态,有几种途径可以实现这个目的

使用不可变对象

在改变状态之前检查参数有效性,提前抛出异常

将可能失败的操作放在改变状态之前执行,这样失败是可以提前结束,不至于使对象处于不一致的状态

写恢复代码(不常用),一般是对于已经持久化的数据

使操作在一个临时拷贝上执行

有时,并不总能实现失败的原子性,例如两个线程不安全的并发修改对象的状态

规范上来讲,任何调用失败都应该使对应状态位于之前的状态,如何有不一致,应该在文档中描述出来

不要忽略异常

对于异常,除了关闭InputStream时,其他时候都不要忽略异常

对异常

要么处理

要么传播出去

此建议对于checked 和unchecked异常都使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: