异常传播指的是异常事件从嵌套的 try
块或嵌套的方法调用中移动的过程。一个 try
块可以嵌套在另一个 try
块内。同样,一个方法可以调用另一个方法,每个方法都可以独立地处理异常或抛出已检查/未检查的异常。每当在一个嵌套的 try
块或方法中引发异常时,该异常会被推送到栈中。异常从子 try
块或子方法传播到父 try
块或父方法,依此类推。
嵌套 try
块的语法
嵌套的 catch
块的语法如下所示:
try {
try {
}
catch(ExceptionType1 e1){
}
} catch (ExceptionType2 e1) {
}
嵌套方法调用的语法
嵌套方法调用的语法如下所示:
method1(){
try {
method2();
} catch (ExceptionType2 e1) {
}
method2(){
}
前面的语句演示了两个 try/catch
块和方法,但实际上可以有任意数量的块和方法。如果在受保护的子代码中发生异常,异常会被抛到子列表的 catch
块。如果抛出的异常类型与 ExceptionType1
匹配,则在那里被捕获;如果不匹配,则异常会传递给父 catch
语句。这个过程会一直持续,直到异常被捕获或穿过所有 catch
块,在这种情况下,当前方法停止执行,异常被抛给调用堆栈上的前一个方法。
Java 中异常传播的规则
-
子
catch
块应具有特定的异常,以便于更好的代码清晰度。
-
父
catch
块可以处理更通用的异常,这样如果子 catch
块无法处理异常,则父 catch
块可以处理它。
-
在子
catch
块与父 catch
块中使用的异常层次结构上没有限制。
-
如果异常在子
catch
块中正确处理,则在父级中可以引发并处理另一个异常。
Java 异常传播示例
下面的代码片段展示了异常事件从子方法传播到父方法的过程。在这个例子中,我们在子方法中通过除以零来创建一个错误。子方法抛出异常。现在,在父方法的 try
块中,我们处理异常并打印错误消息。
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
int a = 3;
int b = 0;
try {
System.out.println("结果:" + divide(a, b));
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
}
private static int divide(int a, int b) {
return a / b;
}
}
输出:
/ by zero
更多示例
示例 1
下面的代码片段展示了异常事件从子方法传播到父方法的过程。在这个例子中,我们在子方法中通过除以零来创建一个错误。子方法抛出异常。现在,在父方法中,我们没有处理异常。JVM 将拦截异常并打印错误消息。
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
int a = 3;
int b = 0;
System.out.println("结果:" + divide(a, b));
}
private static int divide(int a, int b) {
return a / b;
}
}
输出:
主线程异常:java.lang.ArithmeticException: / by zero
at com.tutorialspoint.ExcepTest.divide(ExcepTest.java:12)
at com.tutorialspoint.ExcepTest.main(ExcepTest.java:8)
示例 2
下面的代码片段展示了异常事件在子方法内部停止而不是传播到父方法的情况。在这个例子中,我们在子方法中通过除以零来创建一个错误。子方法处理了异常。现在,在父方法中,我们没有收到任何异常。
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
int a = 3;
int b = 0;
System.out.println("结果:" + divide(a, b));
}
private static int divide(int a, int b) {
try {
return a / b;
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
return 0;
}
}
输出:
/ by zero
结果:0