异常传播指的是异常事件从嵌套的 try 块或嵌套的方法调用中传播的过程。一个 try 块可以嵌套在另一个 try 块中。同样一个方法可以调用另一个方法每个方法可以独立处理异常或者抛出 checked/unchecked exceptions。每当在嵌套的 try 块/方法中引发异常时该异常会被推入 Stack。异常会从子 try 块传播到父 try 块或者从子方法传播到父方法依此类推。语法 - 嵌套 Try 块嵌套 catch 块的语法如下所示 −try { // 父 try 块 try { // 子 try 块 } catch(ExceptionType1 e1){ // 子 catch 块 } } catch (ExceptionType2 e1) { // 父 catch 块 }语法 - 嵌套方法调用嵌套方法调用的语法如下所示 −method1(){ // 父方法 try { // 父 try 块 method2(); } catch (ExceptionType2 e1) { // 父 catch 块 } method2(){ // 子方法 // 抛出异常的代码 // 此异常将由父方法处理 }前面的语句演示了两个 try/catch 块和方法但你可以有任意数量的它们。如果在受保护的子代码中发生异常则异常会被抛到子列表的 catch 块中。如果抛出的异常的数据类型匹配 ExceptionType1则在那里被捕获。如果不匹配则异常会向上传递到父 catch 语句中。这一过程持续进行直到异常被捕获或者穿过所有 catch 块在这种情况下当前方法停止执行异常被抛到调用栈上的前一个方法中。Java 中的异常传播规则子 catch 块应使用特定的异常类型以提高代码清晰度。父 catch 块可以处理更通用的异常以便如果子 catch 块无法处理该异常则父 catch 块可以处理它。子 catch 块与父 catch 块中使用的异常层次结构没有限制。如果子 catch 块正确处理了异常则在父块中可以引发并处理另一个异常。示例 - 异常传播以下代码片段展示了异常事件从子方法传播到父方法的示例。在此示例中我们在子方法中通过将一个值除以 0 来创建错误。子方法抛出异常。现在在父方法中在 try 块内我们处理该异常并打印错误消息。Example.groovyclass Example { static void main(String[] args) { int a 3; int b 0; try { println(result: divide(a,b)); }catch(ArithmeticException e) { println(e.getMessage()); } } static int divide(int a, int b) { return a / b; } }输出Division by zero示例 - 异常向 JVM 传播以下代码片段展示了从子方法向父方法传播异常事件。在本示例中我们在子方法中通过将一个值除以 0 来制造错误。子方法抛出异常。现在在父方法中我们不处理该异常。JVM 将拦截该异常并打印错误消息。Example.groovyclass Example { static void main(String[] args) { int a 3; int b 0; println(result: divide(a,b)); } static int divide(int a, int b) { return a / b; } }输出Caught: java.lang.ArithmeticException: Division by zero java.lang.ArithmeticException: Division by zero at Example.divide(Example.groovy:10) at Example.main(Example.groovy:6) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)示例 - 停止异常传播以下代码片段展示了异常事件在子方法内部停止传播而不是流向父方法。在本示例中我们在子方法中通过将一个值除以 0 来制造错误。子方法处理了该异常。现在在父方法中我们不会收到任何异常。Example.groovyclass Example { static void main(String[] args) { int a 3; int b 0; println(result: divide(a,b)); } static int divide(int a, int b) { try { return a / b; }catch(ArithmeticException e) { println(e.getMessage()); } return 0; } }输出Division by zero result:0