===== 异常结构 =====
{{:pasted:20160301-214457.png}}
===== 异常种类 =====
* Error:程序无法处理的异常(如:OutOfMemoryError)
* Exception:程序可以处理的异常。还分两种
* 运行时异常:不需要显示处理也能编译,但最终需要被捕获(如:NullPointerException)
* 检查异常:需要显示处理或抛出异常,否则编译不通过(如:IOException)
* java认为Checked异常都是可以被处理(修复)的异常,所以必须强制处理
===== 异常抛出 =====
* 导致当前流程无法正常继续执行的错误,或者,程序可以处理的错误 -> 抛出RunTimeException
* 空指针
* 除数为0等等
* 程序无法处理的错误 -> 抛出Error
* 内存溢出
* 导致程序永远无法正常工作错误 -> 抛出Error
* 关键数据库ip配置错误
===== 异常处理 =====
* 如果知道异常如何处理,则捕获并且处理
* 如果自己不能修复,则继续抛出
* 遇到检查异常,可以转换成运行时异常
try {
FileInputStream in=new FileInputStream("/a.txt");
} catch (FileNotFoundException e) {
throw new RuntimeException("file exception");
}
* 程序最外层统一处理异常
* 如果程序种使用了assert,那异常捕获的时候要注意assert的异常类型(Error类型)
try {
main(); // 不一定是main函数,这里只最上层的函数
} catch (RuntimeException e){ // 所有运行时异常在这里统一处理
System.out.println("handle RuntimeException error here");
} catch (Error e){ // 如果是junit异常,捕获并处理
if(e.getClass().toString().contains("junit")) {
System.out.println("handle junit error here");
}
else { // 如果不是junit异常,则一定是系统级异常,程序已经无法处理,抛出异常,终止程序
System.out.println("handle error here");
throw e;
}
}
===== 自定义异常 =====
异常是一个比较耗时的操作,异常性能差是因为fillInStackTrace方法,该方法是带锁的并且需要填充线程异常栈信息。
而我们的业务类异常是不需要记录异常栈的,可以考虑覆写fillInStackTrace方法减小性能开支(据说覆写该方法能提高10倍性能)。
class BizException extends Exception{
public BizException(String message) {
super(message);
}
public Throwable fillInStackTrace() {
return this;
}
}