一.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()完成: