解析Java異常的棧軌跡及其相干辦法。本站提示廣大學習愛好者:(解析Java異常的棧軌跡及其相干辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是解析Java異常的棧軌跡及其相干辦法正文
一.打印棧軌跡的辦法
自動挪用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的異常棧信息均如圖:
分歧的是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)