异常处理最佳实战

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/

http://blog.jobbole.com/18291/

时间: 2024-12-14 18:42:53

异常处理最佳实战的相关文章

异常处理最佳实践

一.异常的分类 常规分类: 1.运行时异常(RuntimeException): 2.编译时异常(CheckedException) 用途分类: 1.打断(终止)程序继续往下运行: 2.打断程序继续往下运行,并将异常原因和信息送往上层. 特点分类: 1.可以获得异常的原因: 2.可以获得异常的代号: 3.可以获得异常的错误行号: 4.可以获得异常的堆栈信息(程序运行轨迹): 5.可以获得异常的类型: ……等. 判断分类: 1.可以预判(预先判断).自主定义的异常,比如我们自己写程序,在Servi

Scala深入浅出实战经典-----002Scala函数定义、流程控制、异常处理入门实战

002-Scala函数定义.流程控制.异常处理入门实战 Scala函数定义 语句结束无分号 定义无参函数 def 函数名称(参数名称:参数类型)[:Unit=]{ 函数体 } 老师的代码 我的实际代码 原因是集成开发环境自带的版本为2.11.0 变量 常量(不可变)声明 val 变量声明 var 无参函数的调用也无需加括号() 定义有参有返回值的函数 def 函数名称(参数名称:参数类型...):返回值类型={ 函数体 } 老师代码 注意最后一个是b是本函数的返回值 默认最后一行为返回值 流程控

MySQL 5.7--------SSL连接最佳实战

                                                                                         MySQL 5.7--------SSL连接最佳实战 1. 背景 * 在生产环境下,安全总是无法忽视的问题,数据库安全则是重中之重,因为所有的数据都存放在数据库中 * 当使用非加密方式连接MySQL数据库时,在网络中传输的所有信息都是明文的,可以被网络中所有人截取,敏感信息可能被泄露.在传送敏感信息(如密码)时,可以采用

Scala深入浅出实战经典-----002-Scala函数定义、流程控制、异常处理入门实战

002-Scala函数定义.流程控制.异常处理入门实战 Scala函数定义 语句结束无分号 定义无参函数 def 函数名称(参数名称:参数类型)[:Unit=]{ 函数体 } 老师的代码 我的实际代码 原因是集成开发环境自带的版本为2.11.0 变量 常量(不可变)声明 val 变量声明 var 无参函数的调用也无需加括号() 定义有参有返回值的函数 def 函数名称(参数名称:参数类型...):返回值类型={ 函数体 } 老师代码 注意最后一个是b是本函数的返回值 默认最后一行为返回值 流程控

002-Scala函数定义、流程控制、异常处理入门实战

002-Scala函数定义.流程控制.异常处理入门实战 Scala函数定义 语句结束无分号 定义无参函数 def 函数名称(参数名称:参数类型)[:Unit=]{ 函数体 } 老师的代码 我的实际代码 原因是集成开发环境自带的版本为2.11.0 变量 常量(不可变)声明 val 变量声明 var 无参函数的调用也无需加括号() 定义有参有返回值的函数 def 函数名称(参数名称:参数类型...):返回值类型={ 函数体 } 老师代码 注意最后一个是b是本函数的返回值 默认最后一行为返回值 流程控

vue2 入门 教程 单页应用最佳实战[*****]

推荐 vue2 入门 教程 -------- 看过其他的,再看作者的,很赞 vue2 入门 教程 单页应用最佳实战 :  具体在 https://github.com/MeCKodo/vue-tutorial ----------------------------- 通过本文,我们可以学习到许多关于vue的特性. 1.了解了vue-cli脚手架 2.初步对webpack有了一些了解和认识 3.如何用.vue愉快的开发 4.使用vuex进行组件通信 5.路由(子路由)的应用 6.使用 vue-d

日志最佳实战

日志最佳实战 1. logback 2. 开发debug,生产info , 异常中用error 3. 使用self4j的占位符方式输入日志.多个参数输出,参数项使用数组的形式.举例 : logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol); 此种形式在确定日志输出级别前,不会拼接字符串. // LOGGER.isDebugEnabled() 4. 访问日志和错误日志记录到不同的文件中,方便查询

02Scala学习-Scala函数定义、流程控制、异常处理入门实战

一 Scala 函数的定义 按照以下格式定义scala函数. def 函数名称(函数输入参数类型){ //函数的实现提 } 1) 第一个简单的例子 HelloWorld object Test2 { def main(args: Array[String]):Unit = { println("HelloWorld") } } a)可以看到输出语句的结尾没有以“;”结束,因为scala的设计者认为,多大一个字符对开发者来说是痛苦的. 他不太赞成在语句的结束写 “;” , 但你也可以写 

02Scala-函数定义、流程控制、异常处理入门实战

一 Scala 函数的定义 DT大数据梦工厂的微信公众号是DT_Spark,每天都会有大数据实战视频发布 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2 按照以下格式定义scala函数. def 函数名称(函数输入参数类型){ //函数的实现提 } dem