1. 只在必要使用异常的地方才使用异常,不要用异常去控制程序的流程.。慎地使用异常,异常捕获的代价非常高昂,异常使用过多会严重影响程序的性能。
2. 切忌使用空catch块。千万不要使用空的catch块,空的catch块意味着你在程序中隐藏了错误和异常,并且很可能导致程序出现不可控的执行结果。如果你非常肯定捕获到的异常
不会以任何方式对程序造成影响,最好用Log日志将该异常进行记录,以便日后方便更新和维护。
3. 异常信息放到一个单独的文件中
4. 在finally中释放资源
5. 如果客户端可以从异常中采取行动进行恢复的,就使用checked exception,如果客户什么也做不了,就用unchecked exception。我指的是,不仅仅是记录异常,还要采取措施来恢复。
6. 如果自定义的异常没有提供有用的信息的话,请不要创建它们。尽量使用java定义好的异常类,而非我们自己创建的异常类。它们使我们的代码易读,也避免代码消耗更多内存。
7. 如果你将一个异常包装成另一种异常时,构造一个新异常要传递源异常。
8. 日志中记录详细的异常信息。
9. 记录异常,仅记录一次
异常处理的最佳实践到底是什么?
首先要理解的是,异常到底是什么,我觉得异常分两类。
第一是业务异常,就是处理业务的时候80%的时候是没问题的,但可能有20%的时候事情没有按理想的方向发展。例如注册用户的时候,正常情况是注册成功,但可能用户提交请求的时候,系统发现用户名
已经被别人注册了,这是就可以抛出一个UserAlreadyExistsException。
第二是系统异常,系统异常与具体业务流程没有直接的关系,例如编程错误导致的NullPointExcpetion,还有环境问题,例如磁盘损坏或者网络连接不稳定造成了IOException。
先谈谈业务异常,业务异常应该是接口的一部分,该接口的用户应该能够处理该异常。也就是说,在实现接口之前,就应该定义清楚这个接口会抛出怎样的异常,例如注册用户这个接口就应该明确定义会
抛出UserAlreadyExistsException,并辅以必要文档,那调用者就知道怎么去处理。如果你在接口声明异常,那你一定要确保接口的调用者能够处理之。例如对应于 UserAlreadyExistsException,用户
界面可以提示用户该ID已存在,那用户可以使用另外的ID来注册。注意,处理异常不是简单的catch,然后随便打印点日志那么简单,业务异常的处理应当遵照业务流程。
而系统异常由于没有实际业务意义,调用者往往是不知道如何处理的。例如注册用户的时候收到一个IOException,你只会一头雾水。那系统异常应该如何处理呢?有这么几个选择:
1). 能在底层处理的就本地处理掉,例如网络连接超时异常,可以编写代码尝试再次连接。
2). 能翻译为业务异常的就翻译,有时候你可能发现某个IOException对应有实际的业务意义,但不要直接抛出,而是应该Exception Chaining技术来翻译,
例如 throw new MyOwnException(“sorry, …”, ioe),这样既不至于丢失原始信息,业务接口也更容易理解。
有时候业务异常和系统异常的角色会相互转换,例如 FileNotFoundException 对于文件处理这个领域来说是业务异常,可对于我的应用来说,可能只是一个系统异常。
上述是我认为异常处理最核心最有用的实践,除此之外还有不少前人总结的经验,包括:
-
记录异常,但只记录一次。(不要丢失历史)
-
不要返回及传Null值。(避免NullPointException和不必要的检查)
-
尽量重用JDK自带的异常。(以降低学习成本)
-
在自定义异常中存储异常相关信息字段。(以方便日后处理)
-
永远不要直接忽略异常。(不要丢失历史)
-
为异常声明写Javadoc。(对你的用户有好些)
-
不要 throws 或者 catch 顶层的 Exception 类。(天知道Exception对应什么业务信息)
参考文章:http://www.oschina.net/translate/10-exception-handling-best-practices-in-java-programming
http://www.juvenxu.com/2011/03/30/exception-handling-best-practices/