Java异常链

Posted 海恋天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java异常链相关的知识,希望对你有一定的参考价值。

一.Java中的异常链

目的:追踪到异常最初发生的位置

方式:重新构造异常

 1 public class Rethrowing {
 2 
 3     //模拟A层异常
 4     public static void A() throws Exception {
 5         System.out.println("现在在A层:");
 6         throw new Exception("A层出现异常");
 7     }
 8 
 9     //模拟B层
10     public static void B() throws Exception {
11         try {
12             A();
13         } catch (Exception e) {
14             System.out.println("现在在B层: ");
15             e.printStackTrace();
16             System.out.println("B层执行e.printStackTrace()完成: ");
17             throw e;//此异常对象是原始异常对象,持有全部站轨迹信息
18         }
19     }
20 
21     //模拟C层
22     public static void C() throws Exception {
23         try {
24             B();
25         } catch (Exception e) {
26             System.out.println("现在在C层: ");
27             e.printStackTrace();
28             System.out.println("C层执行e.printStackTrace()完成: ");
29             //更新调用栈信息,抛出的异常对象中包含的是重新抛出点的信息,有关原来异常发生点的信息会丢失。
30             //会丢失原异常抛出点到当前抛出点的栈轨迹
31             //throw (Exception)e.fillInStackTrace();
32 
33             //以此异常为cause构造新的异常并抛出,可通过这个异常链追踪到异常最初发生的位置
34 //            throw new RuntimeException(e);
35             throw e;
36         }
37     }
38 
39     public static void main(String[] args) {
40 
41         try {
42             C();
43         } catch (Exception e) {
44             System.err.println("现在在main层:");
45             e.printStackTrace();
46             System.out.println("main层执行e.printStackTrace()完成: ");
47         }
48     }
49 }

结果:

 1 现在在A层:
 2 现在在B层: 
 3 java.lang.Exception: A层出现异常
 4     at day12.Rethrowing.A(Rethrowing.java:12)
 5     at day12.Rethrowing.B(Rethrowing.java:18)
 6     at day12.Rethrowing.C(Rethrowing.java:30)
 7     at day12.Rethrowing.main(Rethrowing.java:56)
 8 B层执行e.printStackTrace()完成: 
 9 现在在C层: 
10 java.lang.Exception: A层出现异常
11     at day12.Rethrowing.A(Rethrowing.java:12)
12     at day12.Rethrowing.B(Rethrowing.java:18)
13     at day12.Rethrowing.C(Rethrowing.java:30)
14     at day12.Rethrowing.main(Rethrowing.java:56)
15 C层执行e.printStackTrace()完成: 
16 现在在main层:
17 java.lang.Exception: A层出现异常
18     at day12.Rethrowing.A(Rethrowing.java:12)
19     at day12.Rethrowing.B(Rethrowing.java:18)
20     at day12.Rethrowing.C(Rethrowing.java:30)
21     at day12.Rethrowing.main(Rethrowing.java:56)
22 main层执行e.printStackTrace()完成: 

将 throw e;改为 throw new RuntimeException(e); 用来重新构造异常则

结果:

 1 现在在A层:
 2 现在在B层: 
 3 java.lang.Exception: A层出现异常
 4     at day12.Rethrowing.A(Rethrowing.java:12)
 5     at day12.Rethrowing.B(Rethrowing.java:18)
 6     at day12.Rethrowing.C(Rethrowing.java:30)
 7     at day12.Rethrowing.main(Rethrowing.java:48)
 8 B层执行e.printStackTrace()完成: 
 9 现在在C层: 
10 java.lang.Exception: A层出现异常
11     at day12.Rethrowing.A(Rethrowing.java:12)
12     at day12.Rethrowing.B(Rethrowing.java:18)
13     at day12.Rethrowing.C(Rethrowing.java:30)
14     at day12.Rethrowing.main(Rethrowing.java:48)
15 C层执行e.printStackTrace()完成: 
16 现在在main层:
17 java.lang.RuntimeException: java.lang.Exception: A层出现异常
18     at day12.Rethrowing.C(Rethrowing.java:40)
19     at day12.Rethrowing.main(Rethrowing.java:48)
20 Caused by: java.lang.Exception: A层出现异常
21     at day12.Rethrowing.A(Rethrowing.java:12)
22     at day12.Rethrowing.B(Rethrowing.java:18)
23     at day12.Rethrowing.C(Rethrowing.java:30)
24     ... 1 more
25 main层执行e.printStackTrace()完成: 

能够追溯到最原始的异常在A层!

补充:

  • e.getCause():返回到最初发生异常的位置

修改main函数,将 e.printStackTrace();改为System.out.println("最初异常发生的位置:"+e.getCause().getMessage()); 

 1 public static void main(String[] args) {
 2 
 3     try {
 4         C();
 5     } catch (Exception e) {
 6 
 7         System.err.println("现在在main层:");
 8 //            e.printStackTrace();
 9         System.out.println("最初异常发生的位置:"+e.getCause().getMessage());
10         System.out.println("main层执行e.printStackTrace()完成: ");
11 
12     }
13 }

结果:

 1 现在在A层:
 2 现在在B层: 
 3 java.lang.Exception: A层出现异常
 4     at day12.Rethrowing.A(Rethrowing.java:12)
 5     at day12.Rethrowing.B(Rethrowing.java:18)
 6     at day12.Rethrowing.C(Rethrowing.java:30)
 7     at day12.Rethrowing.main(Rethrowing.java:48)
 8 B层执行e.printStackTrace()完成: 
 9 现在在C层: 
10 java.lang.Exception: A层出现异常
11     at day12.Rethrowing.A(Rethrowing.java:12)
12     at day12.Rethrowing.B(Rethrowing.java:18)
13     at day12.Rethrowing.C(Rethrowing.java:30)
14     at day12.Rethrowing.main(Rethrowing.java:48)
15 C层执行e.printStackTrace()完成: 
16 现在在main层:
17 最初异常发生的位置:A层出现异常
18 main层执行e.printStackTrace()完成: 

以上是关于Java异常链的主要内容,如果未能解决你的问题,请参考以下文章

异常+异常链

java异常——捕获异常+再次抛出异常与异常链

片段中的 EditText 上的空指针异常 [重复]

Java异常处理机制

java 第50节 Java中的异常链

Java异常链