1.前言
- 马丁路德金说:“I have a dream !”,程序员说:“我也有一个梦想”,那就是写出永远不会出错(bug)的代码。梦想得有,但是实现不了,实现不了怎么办?为梦想挖个坑,埋了他,这个坑就叫做异常!
- 我想从以下几个方面说说我对异常的理解
- 概念
- 语法
- 工作
- 性能
2.概念
- java异常分为Exception 和Error ,这两者都继承自Throwable,Throwable 继承自Object,Exception 和Error 体现了java平台设计者对不同异常情况的分类。Exception是程序正常运行中可以预料到的意外情况,可能并且应该被捕获,进行相应处理。Error是指在正常情况下不大可能出现的异常,绝大部分Error异常会导致程序处于非正常的,不可恢复的状态。
- Exception 异常又分为可检查(checked)异常和不检查(unchecked)异常!继承RuntimeException的异常都为不检查(unchecked),即编译器不用显示捕获。
3.语法
- 掌握throw,throws,try-catch-finally,语法和关键字。
- 掌握java7新加的try-with-resources和multiple catch,语法特性。
4.工作
- 处理异常的原则
try{
//业务代码
....
Thread.sleep(1000L);
} catch(Exception e){
//ignore it;
}
这段代码虽然短,但是违反了异常处理的两个基本原则。
- 尽量不要捕获类似Exception 这样的通用异常,而应该捕获特定异常。
- 不要生吞异常,生吞异常往往是假设这段代码可能不会发生,或者感觉忽略异常是无所谓的,但是千万不要在产品代码做这种假设。
- 不要在finally代码块中处理返回值。
异常输出到日志中
很多人喜欢在catch中使用e.printStackTrace()
打印出异常信息,但是在稍微复杂的系统中就会出现不知道到底输出到哪里。尤其是在分布式系统中。坚持 Throw early,catch late 原则。就是尽早发现异常并且抛出,捕获异常后怎么处理很苦恼,最差就是生吞异常,如果不知道怎么做就保留异常信息然后抛出到更高层,高层业务会更清楚,方便对异常处理。
5.性能
- try-catch 代码块会产生额外的性能开销,换个角度说就是会影响JVM对代码的优化。尽量不要一个大的try 包含整段代码。
- java 每实例化一个exception 就会对当前的栈进行快照,如果发生频繁,这样的开销不可忽略。
- 如果发现服务器反应慢,吞吐量下降时,坚持频繁实例化的Exception也是一个方向。