java异常处理的艺术

/ 技术收藏 / 没有评论 / 391浏览

笔者曾经接触过俗称的shi山项目,代码中满篇的try-catch,有次测试人员发现qa有数据不对,遂提出bug,我们这里的开发人员翻取k8s的日志,死活没有找到报错信息,貌似程序全部正常,但却产生了非正常的数据。于是这名开发人员找到了我。不看不知道,一看吓一跳,service,controller,几乎所有方法都套上了try-catch,最最关键的是,catch的是Exception,之后居然什么也没干,甚至异常打印都没有,继续往下走。

能写出这种代码的人,我相信还是少数,大部分人起码不会无脑处理所有异常。在系统开发中,不合时宜的处理异常,不合时宜的抛出异常还是比较常见的。同时不当,不合时宜的异常处理也会给系统带来灾难。

要弄清异常怎么处理,我们就要弄明白异常是怎么产生的,处理的目的是什么。 异常可能来源于外部调用,比如读写文件,读写流,都会抛出io异常,也可能来源于代码本身,比如NPE,再比如我们期望值和实际值不相同,这时我们可能会主动抛出异常,合理的利用好断言,可以极大的提升自己代码的健壮性,以及代码的整洁度。

那么我们对这些异常应该怎么办呢?其实这个问题也没有标准答案,需要结合自己的具体情况。 举个栗子,我们要读取文件a.txt来获取内容,并且复制给变量b。 此时如果a.txt文件不存在,那就会抛出not found异常。

但是这个异常是否处理则需要看具体情况,假设a.txt这个文件很重要,读取不到其中的值,那这程序就走不下去了,那么此时则不应该吞下这个异常,最好的处理方式就是捕获异常,并且抛出自己的封装异常,给出友好提示。

若a.txt这个文件不重要,如果读取不到的话,我们就可以给b一个默认值,此时就可以捕获异常,在异常 中打入debug日志,并且给b一个默认值即可。

一般情况,service中的异常都是需要往外抛的,抛给调用方。controller中一般也不处理异常,把异常都抛到外面的异常拦截器里统一处理。如果遇到需要处理的异常,则要符合最小捕获原则,比如抛出的是IllegalAccessException,千万不要catch父类Exception。很可能处理了其他异常。

合理的利用异常,以及断言,会让你的代码看起来很简洁清爽,而且健壮。