Java异常传播是怎么回事?该怎么用?

文章导读
Previous Quiz Next 异常传播 异常传播指的是异常事件从嵌套的 try 块或嵌套的方法调用中传递的过程。一个 try 块可以嵌套在另一个 try 块内。类似地,一个方法可以调用另一个方法,每个方法可以独立处理异常,或者抛出 checked/unchecked
📋 目录
  1. 异常传播
  2. Java 中异常传播的规则
  3. Java 异常传播示例
  4. 更多示例
A A

Java - 异常传播



Previous
Quiz
Next

异常传播

异常传播指的是异常事件从嵌套的 try 块或嵌套的方法调用中传递的过程。一个 try 块可以嵌套在另一个 try 块内。类似地,一个方法可以调用另一个方法,每个方法可以独立处理异常,或者抛出 checked/unchecked 异常。每当在嵌套的 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 块正确处理了异常,那么在父块中,可以抛出并处理另一个异常。

Java 异常传播示例

以下代码片段展示了异常事件从子方法向父方法传播的过程。在这个示例中,我们在子方法中通过将一个值除以 0 来创建错误。子方法抛出异常。现在在父方法中,在 try 块内,我们处理该异常并打印错误消息。

package com.;

public class ExcepTest {

   public static void main(String args[]) {
      int a = 3;
      int b = 0;
      try {
         System.out.println("result:" + 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

以下代码片段展示了从子方法到父方法的异常事件传播。在这个示例中,我们在子方法中通过将一个值除以 0 来制造错误。子方法抛出异常。现在在父方法中,我们没有处理该异常。JVM 将拦截该异常并打印错误消息。

package com.;

public class ExcepTest {

   public static void main(String args[]) {
      int a = 3;
      int b = 0;
      System.out.println("result:" + divide(a,b));
   }

   private static int divide(int a, int b) {
      return a / b;
   }
}

输出

Exception in thread "main" java.lang.ArithmeticException: / by zero
   at com..ExcepTest.divide(ExcepTest.java:12)
   at com..ExcepTest.main(ExcepTest.java:8)

示例 2

以下代码片段展示了异常事件在子方法内部停止传播,而不是流向父方法。在这个示例中,我们在子方法中通过将一个值除以 0 来制造错误。子方法处理了该异常。现在在父方法中,我们不会收到任何异常。

package com.;

public class ExcepTest {

   public static void main(String args[]) {
      int a = 3;
      int b = 0;
      System.out.println("result:" + 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
result:0