异常定义是组织当前方法或作用于继续执行的问题。
异常分类
- Error 不能捕获的严重问题
- Exception 可捕获的异常
异常分布图
按照Checked和UnChecked划分
checked异常
正确的运行中,容易出现的,情理可容的异常,一旦发生必须处理。除了RuntimeException以外的Exception,编译器会检查,必须处理(捕获或抛出声明)。
unchecked异常
RuntimeException及子类Error。
Exception按照处理和不处理划分
- 运行时异常:RuntimeException,不一定处理
- 编译异常:除RuntimeException外的异常,必须处理
派生类限制
- 派生类构造器异常必须包含基类异常
- 派生类构造器不能捕获基类构造器异常
- 覆盖的方法,不能跑出基类未定义异常
- 派生类可不跑出异常,即使基类有定义
异常处理最佳实践
- 尽量避免返回null
- catch中别不谢代码,最好打印异常信息
- 能抛检查型异常就不抛非检查型异常
- DB异常不应显示到客户端
- 数据库连接等流,在处理后要关闭
异常链
在捕获一个异常的同事抛出另一个异常,且要包含捕获的信息
try {
// Do Something
} catch (Exception1 e) {
throw new Exception2(e);
}
// 这样处理才能用getCause或initCause来访问异常资源
Exception有个initCause方法,可以将异常类型链起来
Java7新特性
- 1个catch可以捕获多个异常,多个异常不应该是相同类型,否则报错
catch(Exception1 e | Exception2 e) {
}
// Exception1 不应是Exception2的子类
- try with resources
可以确保在try语句结束后关闭所有资源
static String readFirstLineFromFile (String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(Path)) {
returnbr.readLine();
}
}
资源是BufferedReader,生命语句在try口号中,在Java7或更晚版本中,BufferedReader实现了java.lang.AutoCloseable接口
题外:Connection与Session和其他对象的close方法都实现了AutoCloseable接口
- Throwable类增加了addSuppressed记录异常
OutOfMemoryError处理
发生原因:
1. 内存中加载的数量过于庞大
2. 集合中有对象引用使用完后未清空
3. 启动参数过小
4. 死循环或死循环产生过多重复对象
5. 第三方软件异常
处理方式:
1. 增加jvm内存大小
2. 优化程序,释放垃圾
排查:
1. 检查代码中死循环与递归调用
2. 大循环重复产生新对象实体
3. DB查询是否有一次获取所有数据
4. List Map使用完未清除