随着项目开发的规模越来越大,越往底层,可能抛出的异常类型也会越来越多。
如果上层想要处理这些异常,就需要挨个的写很 try-catch
语句块来捕捉异常,这样是很麻烦的。
如果我们对底层抛出的异常捕获后,抛出一个新的统的异常,的确可以避免这个问题。但是直接抛出一个新的异常,又可能会造成最原始的异常信息丢失,不利于排查问题。
这里只是为了演示,实际工作都是Spring
统一异常处理,没有try-catch
,这里演示的是异常链传递异常的问题。
例子如下:
public class Test {
public static void main(String[] args) {
try {
checkEx3();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void checkEx3() throws Exception {
try {
checkEx2();
} catch (Exception e) {
Exception e1 = new Exception("第3个异常");
throw e1;
}
}
public static void checkEx2() throws Exception {
try {
checkEx1();
} catch (Exception e) {
Exception e2 = new Exception("第2个异常");
throw e2;
}
}
public static void checkEx1() throws Exception {
throw new Exception("第1个异常");
}
}
打印结果如下
你会发现,最初出现的是异常1,然后异常2,这些信息都不见了,只出现了最后一次异常3,这对于排错非常不利。
解决方案如下:
public class Test {
public static void main(String[] args) {
try {
checkEx3();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void checkEx3() throws Exception {
try {
checkEx2();
} catch (Exception e) {
// 异常链写法1
Exception e1 = new Exception("第3个异常");
e1.initCause(e); // 异常链信息的传递
throw e1;
// 异常链写法2
// throw new Exception("第3个异常", e);
}
}
public static void checkEx2() throws Exception {
try {
checkEx1();
} catch (Exception e) {
// 异常链写法1
Exception e2 = new Exception("第2个异常");
e2.initCause(e); // 异常链信息的传递
throw e2;
// 异常链写法2
// throw new Exception("第2个异常", e);
}
}
public static void checkEx1() throws Exception {
throw new Exception("第1个异常");
}
}
这样就能看到最初的第1个异常和第2个异常了。采用异常链,在保有底层异常信息的基础上,将多层次异常以链路方式进行封装,对后续追查定位BUG是非常有利的
推荐异常链写法1。因为initCause
方法相对更加灵活,可以在异常对象构造完成单独进行异常信息赋值。
异常链写法2是利用异常的根类Throw
中提的带参构造方法 Throwable (String message, Throwable cause)
实现异常链信息的传递。
对于异常信息传递的作用而言,写法1和2无区别。
欢迎一键三连~
有问题请留言,大家一起探讨学习
----------------------Talk is cheap, show me the code-----------------------