国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

解析Java異常的棧軌跡及其相關方法

2019-11-26 14:51:19
字體:
來源:轉載
供稿:網友

一.打印棧軌跡的方法
主動調用Throwable對象的printStackTrace()=printStackTrace(System.err),printStackTrace(PrintStream),printStackTrace(PrintWriter)中的其中一個。
如果一個Exception沒有被處理,直接在main方法后面throws,程序退出前將調用異常的printStackTrace()方法,最終是Exception in thread "main" + printStackTrace()

二.棧軌跡
1、printStackTrace()

  首先需要明確,這個方法并不是來自于Exception類。Exception類本身除了定義了幾個構造器之外,所有的方法都是從其父類繼承過來的。而和異常相關的方法都是從java.lang.Throwable類繼承過來的。而printStackTrace()就是其中一個。

  這個方法會將Throwable對象的棧軌跡信息打印到標準錯誤輸出流上。輸出的大體樣子如下:

java.lang.NullPointerException     at MyClass.mash(MyClass.java:9)     at MyClass.crunch(MyClass.java:6)     at MyClass.main(MyClass.java:3)

  輸出的第一行是toString()方法的輸出,后面幾行的內容都是之前通過fillInStackTrace()方法保存的內容。關于這個方法,我們后面會講。

  下面看一個例子:

public class TestPrintStackTrace {  public static void f() throws Exception{    throw new Exception("出問題啦!");  }  public static void g() throws Exception{    f();  }  public static void main(String[] args) {    try {      g();    }catch(Exception e) {      e.printStackTrace();    }  }}

  這個例子的輸出如下:

java.lang.Exception: 出問題啦!  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)

  在這個例子中,在方法f()中拋出異常,方法g()中調用方法f(),在main方法中捕獲異常,并且打印棧軌跡信息。因此,輸出依次展示了f―>g―>main的過程。

  2、getStackTrace()方法

  這個方法提供了對printStackTrace()方法所打印信息的編程訪問。它會返回一個棧軌跡元素的數組。以上面的輸出為例,輸出的第2-4行每一行的內容對應一個棧軌跡元素。將這些棧軌跡元素保存在一個數組中。每個元素對應棧的一個棧幀。數組的第一個元素保存的是棧頂元素,也就是上面的f。最后一個元素保存的棧底元素。

  下面是一個使用getStackTrace()訪問這些軌跡棧元素并打印輸出的例子:

public class TestPrintStackTrace {  public static void f() throws Exception{    throw new Exception("出問題啦!");  }  public static void g() throws Exception{    f();  }  public static void main(String[] args) {    try {      g();    }catch(Exception e) {      e.printStackTrace();      System.out.println("------------------------------");      for(StackTraceElement elem : e.getStackTrace()) {        System.out.println(elem);      }    }  }}

  這樣的輸出和printStackTrace()的輸出基本上是一樣的,如下:

java.lang.Exception: 出問題啦!  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)TestPrintStackTrace.f(TestPrintStackTrace.java:3)TestPrintStackTrace.g(TestPrintStackTrace.java:6)TestPrintStackTrace.main(TestPrintStackTrace.java:10)

三.fillInStackTrace方法
native fillInStackTrace()方法將返回一個Throwable對象,它是通過把當前調用棧信息填入原來那個異常對象兒建立的,所以返回的還是原來的異常。
調用此方法的那一行將成為異常新的發生地,有關原來異常發生點的信息會丟失。它的效果等價于捕獲一個異常后,重新拋出另外一種異常。兩者不同的是,fillInStackTrace后的異常還是原來的異常(只是少了棧軌跡而已);而重新拋出一個異常的話,完全跟原異常信息無關了(當然也沒有棧軌跡)。

package com.jyz.study.jdk.exception;   /**  * 棧軌跡  * fillInStackTrace  * @author JoyoungZhang@gmail.com  *  */ public class FillInStackTrace {      public static void main(String[] args) throws Exception {   test1();   }    private static void test1() throws Exception{   try{     test2();   }catch(NullPointerException ex){ //1   throw (Exception)ex.fillInStackTrace(); //2   throw new Exception();   }   }      private static void test2(){   test3();   }      private static void test3(){   throw new NullPointerException("str is null");   }  } 

1和2的異常棧信息均如圖:

20151112171706495.jpg (116×146)

不同的是this本身的信息,控制臺第一行打印的就是this。
1的棧信息  

Exception in thread "main" java.lang.NullPointerException: str is null   at com.jyz.study.jdk.exception.FillInStackTrace.test1(FillInStackTrace.java:20)   at com.jyz.study.jdk.exception.FillInStackTrace.main(FillInStackTrace.java:13) 

 
2的棧信息 

Exception in thread "main" java.lang.Exception   at com.jyz.study.jdk.exception.FillInStackTrace.test1(FillInStackTrace.java:21)   at com.jyz.study.jdk.exception.FillInStackTrace.main(FillInStackTrace.java:13) 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 仪征市| 莱州市| 句容市| 保靖县| 绥棱县| 宁晋县| 西盟| 凌云县| 万年县| 尉犁县| 龙井市| 隆尧县| 和顺县| 金门县| 新乡县| 荣成市| 马鞍山市| 渑池县| 河西区| 高州市| 淳化县| 河源市| 拜城县| 乌兰浩特市| 大宁县| 金坛市| 习水县| 固安县| 赣州市| 睢宁县| 怀安县| 曲水县| 竹北市| 沙湾县| 钟山县| 山西省| 来安县| 册亨县| 嘉义市| 木里| 西华县|