各个应用难免比会遇到异常;如何处理异常,各个业务线都有自己的想法和做法;整理了一下网上的通用办法。抛砖引玉,期待给出更有用的意见,共建没有异常的系统。
只对异常的情况,才使用异常
不要把异常机制用来做【判断条件】【循环】等其他逻辑的辅助,异常只做好异常的事情
程序的真实异常使用RuntimeException,可恢复的异常使用Exception具体子类(),不用动ERROR
1:api应该让使用者面向 可恢复的异常变成,尽量处理所有异常(如TimeoutException重试)需要catch;最好抛出异常时,把恢复方案写出来。
2:RuntimeException用于前提条件错误了,不可恢复。需要处理的情况。(如IndexOutOfBoundersException)不应该catch;
3:ERROR是java内建的,够用一般不要继承,非要继承请继承RuntimeException;
4:自定义异常,或者抛出异常,不要直接使用Throwable接口。直接Error,RuntimeExcetption,Exception,这样会更加清洗,不迷惑开发。
避免不必要的受检异常
这种异常虽然可靠,但是需要反复catch处理。(换位思考:如果一个异常抛出后,api的使用者除了打印日志,没有其他恢复手段,就用RunTimeException,如参数错误了。怎么玩也没有用)
避免不必要的受检异常
优先使用标准异常
不要重造轮子,增加代码可读性。
IllegalArgumentException:参数不对
IllegalStateException:对象还未初始化好
NullPointException:企图调用空的对象
ConcurrentModificationException:单线程的对象,被多线程访问时
UnsupportOperationException:某个实现类不打算实现接口的某个方法时
IndexOutOfBoundersException:数组下标越界。
尽量做异常转译
如 get 方法的实现 遇到到了NoSuchElementException,catch它并抛出IndexOutOfBoundsException(NoSuch)。使得异常符合get 的寓意(想象一下再get的时候返回一个NoSuchElementException的迷惑感)(java的标准异常大多支持 异常链,所以还是可以找到NoSuchElementException的原因的)
一个方法如果显示throws异常,都要写好注释@thows
方法的注释,明确两个点,1:什么情况会触发这个异常,2:触发这个异常该如何解决。
方法不要显示的抛出Exception 甚至Throwable等异常的超"累"。一时爽,把所有的异常都写清楚。
Runtime类型的异常也做到文档细致化的话,不要在方法中显示抛出运行是异常,也不要在注释中 throws。
在接口中一定要做好上诉的事情,接口是不仅是调用者的参考,还是实现类的参考。
认真填写Exception的msg字段
有的异常往往难以复现,所以我们在将现场的更多相关的信息(参数和过程变量等),传递给msg字段。
使异常调用不要产生效果(如db变化等)
当出现异常,尽量使得本次调用不产生任何有效的结果,尽量做到本次调用可忽略,保持数据安全
1:通过检查参数可靠性,避免异常发生
2: 通过编写对应修复回滚方法,处理异常。
3: 使得对象都是不可修改
4: 如果一个异常是无法保持原子性,最好文档写清楚。(如concurrentmodificationsException,基本已经把对象改歪了,不可恢复。)
不要catch异常后啥也不干
显而易见,这么做,当故障发生时,将灾难临头,如本来可以打出堆栈,开发通过日志可以知道hbase挂了,被catch了啥也看不到。导致用户的数据怎么都出不来。