为什么80%的码农都做不了架构师?>>>
#1. 不需要Checked异常 Java中的Checked异常,可以说有弊无利,它除了能带来一系列的麻烦,能干的事情Unchecked异常都能干。 ##1.1. 代码污染 首先,当一个方法声明抛出一个Checked异常时,该方法的后面就得加上throws XxxException
;其次,该方法的调用者必须要处理这种异常:要么继续抛出,调用方法也得加上throws XxxException
;要么捕获处理,处理方式可能是记录日志、处理异常流或者再包装一次抛出去;再次,当方法增加另一个Checked异常时,调用者也必须增加这个异常处理,否者代码编译都会出错。 ##1.2. 调用者未必需要或能够处理这个异常 Checked异常强调调用者需要处理这种异常,但绝大部分情况是你根本不知道调用者是否真的需要,或者调用者是否有能力去处理这种异常。例如:SQLException
,调用者除了能记录日志或者包装一下继续抛出,还能做什么?在程序运行过程中用代码去修复错误的SQL语法吗? ##1.3. 都可以用Unchecked异常替代 Checked异常除了强制调用者捕获处理以外,并不比Unchecked异常能够携带更多信息。举个常用的例子:用户登录,可能输入错误的用户名或密码,需要定义两个异常:UserNotFoundException
、PasswordNotMatchException
。把这两个异常定义为Checked异常看上去无可厚非了,调用者显然是必须也能够处理这两个异常的。但反过来想,这两个异常为什么不能定义为Unchecked异常呢?如果调用者需要分别提示用户不同的信息,就分别捕获处理;如果调用者需要统一提示用户:用户名或密码错误,就一起捕获处理;如果调用者本身就有一个顶层统一的异常处理机制呢,就让它直接抛到顶层去处理好了。聪明的Shiro框架就是这么干的,所有的验证异常全部都是Unchecked异常。
#2. 不需要太多的异常 通常情况下,应用这个层面的代码只需要两种异常:系统异常和业务异常。系统异常用来告诉用户:系统繁忙,请稍后再试(通常都是这么委婉,实际可能是某个BUG发作了 ^_^);业务异常,用来告诉用户具体的业务操作提示信息(新增用户时,提示用户名已存在之类的),提示信息放在message属性里就好了。两种异常,也就是两个异常类,它们可以处理掉80%-90%的异常。剩下的情况,只有当需要对某种类型的异常流程进行特殊处理时,才需要增加异常类。例如对外开放API接口时,或许需要定义一个ApiException
,用来返回错误的消息。
#3. 把异常抛到顶层处理 应用可能分很多层,在顶层设计一个异常处理框架来统一处理异常是明智的选择。例如三层结构的web应用,应该在表现层统一处理异常,而不是让异常处理分布在各个层面,像Spring MVC、Struts这些MVC框架都有统一异常处理机制,用好它们就行了。 异常处理往往是开发人员处理不好的一个环节,而这个环节处理又会带来比较大的麻烦,例如错误的处理导致异常中断了,最终连错误日志都找不到。设计好一个顶层异常处理机制,然后告诉开发人员不用处理异常,这样可以尽可能的避免发生这样的问题。 正因如此,异常需要透传到顶层,代码又需要保持优雅,所以Unchecked异常才是必然的选择,优秀的开源框架都是这么干的。