问题描述:在项目中,经常碰到异常被捕获,但却疑惑该异常是否会被抛出还是执行,为了弄清情况,这里使用测试类测试了几种自己常见在项目中异常捕获的情况。
首先我们弄2个方法,分别为父方法,和子方法,且父方法和子方法都有try..catch的部分,代码如下。
@Test
public void father() {
try {
System.out.println("父方法还没出现错误");
System.out.println(1 / 0);
System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错");
} catch (Exception e) {
System.out.println("子方法出现错误");
throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
首先我们测试情况1:父方法没出现错误且不在catch中抛出运行异常异常,子方法出现错误且不在catch中抛出运行时异常,代码截图和输出结果如下:
@Test
public void father() {
try {
// System.out.println("父方法还没出现错误");
// System.out.println(1 / 0);
// System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
// throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错");
} catch (Exception e) {
System.out.println("子方法出现错误");
// throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
结果如下:
此时,子方法catch的代码和try..catch之外的代码正常执行,try..catch部分异常之后的代码不执行,父方法不受子方法影响,正常执行,且不捕获异常。
情况2:父方法没出现错误在catch中抛出运行异常异常,子方法出现错误且不在catch中抛出运行时异常,代码截图和输出结果如下:
@Test
public void father() {
try {
// System.out.println("父方法还没出现错误");
// System.out.println(1 / 0);
// System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错后继续执行");
} catch (Exception e) {
System.out.println("子方法出现错误");
// throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
输出结果如下:
此时输出结果与情况1一致,证明情况1结论正确。
情况3:父方法没出现错误在catch中抛出运行异常异常,子方法出现错误且在catch中抛出运行时异常,代码截图和输出结果如下:
@Test
public void father() {
try {
// System.out.println("父方法还没出现错误");
// System.out.println(1 / 0);
// System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错后继续执行");
} catch (Exception e) {
System.out.println("子方法出现错误");
throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
结果截图如下:
此时子方法抛出运行时异常,父方法catch到子方法的运行时异常,也报错运行时异常,程序终止,此时子、父方法的catch之外的代码都不执行。
情况4:父方法没出现错误在catch中不抛出运行异常异常,子方法出现错误且在catch中抛出运行时异常,代码截图和输出结果如下:
try {
// System.out.println("父方法还没出现错误");
// System.out.println(1 / 0);
// System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
// throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错后继续执行");
} catch (Exception e) {
System.out.println("子方法出现错误");
throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
结果截图如下:
此时,子方法try..catch之外的代码不执行,父方法try..catch之外的代码正常执行且父类正常输出catch内的内容。
情况5:父方法在调用子方法前出现错误且在catch中不抛出运行异常异常,子方法出现错误且在catch中抛出运行时异常,代码截图和输出结果如下:
@Test
public void father() {
try {
System.out.println("父方法还没出现错误");
System.out.println(1 / 0);
System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
// throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错后继续执行");
} catch (Exception e) {
System.out.println("子方法出现错误");
throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
此时输出结果如下:
情况6:父方法在调用子方法前出现错误且在catch中抛出运行异常异常,子方法出现错误且在catch中抛出运行时异常,代码截图和输出结果如下:
@Test
public void father() {
try {
System.out.println("父方法还没出现错误");
System.out.println(1 / 0);
System.out.println("父方法出现错误继续执行");
System.out.println("子方法还没出错,父方法执行");
son();
System.out.println("子方法出错后父方法继续执行");
} catch (Exception e) {
System.out.println("父方法出现错误");
throw new BusinessRuntimeException("父方法出错了!!");
}
System.out.println("父方法catch之外的代码执行");
}
private void son() {
try {
System.out.println("子方法还没出错,子方法执行");
System.out.println(1 / 0);
System.out.println("子方法出错后继续执行");
} catch (Exception e) {
System.out.println("子方法出现错误");
throw new BusinessRuntimeException("子方法出错了!!");
}
System.out.println("子方法catch之外的代码执行");
}
结果截图如下:
此时,父方法发生异常后的代码都没执行,且try..catch之外的代码也没执行。
总结:
try..catch捕获异常时,当方法捕获到异常时会执行catch中的内容,当在catch中抛出运行时异常时,则会终止该方法的继续执行,没有父方法捕获异常时,程序终止。如果有父方法也捕获了异常,则执行父方法catch中的内容,如果在父方法内也抛出运行时异常,则程序终止,否则将正常执行catch之外的内容;如果该方法没抛出运行时异常,则继续执行try..catch外部分的代码,且如果存在父方法的话,则父方法不受影响也不捕获该异常。
在实际使用中,我们也可以在子方法中使用throws的方法将在子方法中发生异常抛给父方法去处理,但此时父方法必须try..catch该子方法。
至于异常原理,这里没做过多的研究。。后续如果有深究再来补充。