HOWTO · Java

Java 中的堆疊跟蹤

本教程演示了堆疊跟蹤是什麼以及如何使用它來除錯 Java 程式碼。

在 Java 中,堆疊跟蹤是一個堆疊陣列。堆疊跟蹤收集程式執行的所有方法的資訊,並告訴我們控制檯中異常或錯誤的位置。

當丟擲異常或發生錯誤時,JVM 會自動顯示堆疊跟蹤。

本教程將演示什麼是堆疊跟蹤以及如何使用它來除錯我們的程式碼。

演示 Java 中的堆疊跟蹤

讓我們執行一個簡單的示例來顯示 Java 中的堆疊跟蹤,然後對其進行描述:

package delftstack;

public class Java_Stack_Trace {
  public static void main(String args[]) {
    try {
      String demo = null;
      System.out.println(getString(demo));
    } catch (NullPointerException e) {
      throw new IllegalStateException(e);
    }
  }

  public static String getString(String demo) {
    System.out.println(demo.toString());
    return demo;
  }
}

上面的程式碼執行一個方法來獲取字串,我們傳遞一個空字串作為引數。我們嘗試捕獲空指標異常。

程式碼將捕獲異常並顯示跟蹤。

輸出:

Exception in thread "main" java.lang.IllegalStateException: java.lang.NullPointerException: Cannot invoke "String.toString()" because "demo" is null
    at Delftstack/delftstack.Java_Stack_Trace.main(Java_Stack_Trace.java:10)
Caused by: java.lang.NullPointerException: Cannot invoke "String.toString()" because "demo" is null
    at Delftstack/delftstack.Java_Stack_Trace.getString(Java_Stack_Trace.java:15)
    at Delftstack/delftstack.Java_Stack_Trace.main(Java_Stack_Trace.java:7)

當程式碼丟擲空指標異常時,輸出顯示堆疊跟蹤。行號為 10 的最頂層方法呼叫是此異常的原因。

堆疊跟蹤還告訴我們,由於字串 demo 在第 7 行為空,因此引發了空點異常。下圖進一步描述了此堆疊跟蹤:

Java 中的堆疊跟蹤

在 Java 中轉儲堆疊跟蹤

堆疊跟蹤包含包、類、方法和行的資訊。Java 有一個內建函式 Thread.dumpStack() 來轉儲所有堆疊跟蹤資訊。

package delftstack;

public class Java_Stack_Trace {
  public static void main(String args[]) {
    Stack_Trace_Demo();
  }

  static void Stack_Trace_Demo() {
    Stack_Trace_Demo1();
  }
  static void Stack_Trace_Demo1() {
    Stack_Trace_Demo2();
  }
  static void Stack_Trace_Demo2() {
    Stack_Trace_Demo3();
  }
  static void Stack_Trace_Demo3() {
    Stack_Trace_Demo4();
  }
  static void Stack_Trace_Demo4() {
    Thread.dumpStack();
  }
}

上面的程式碼包含四個演示方法,然後我們在最後一個方法中呼叫了 dumpstack()。它將顯示所有堆疊跟蹤資訊。

輸出:

java.lang.Exception: Stack trace
    at java.base/java.lang.Thread.dumpStack(Thread.java:1380)
    at Delftstack/delftstack.Java_Stack_Trace.Stack_Trace_Demo4(Java_Stack_Trace.java:21)
    at Delftstack/delftstack.Java_Stack_Trace.Stack_Trace_Demo3(Java_Stack_Trace.java:18)
    at Delftstack/delftstack.Java_Stack_Trace.Stack_Trace_Demo2(Java_Stack_Trace.java:15)
    at Delftstack/delftstack.Java_Stack_Trace.Stack_Trace_Demo1(Java_Stack_Trace.java:12)
    at Delftstack/delftstack.Java_Stack_Trace.Stack_Trace_Demo(Java_Stack_Trace.java:9)
    at Delftstack/delftstack.Java_Stack_Trace.main(Java_Stack_Trace.java:5)

這個堆疊也可以像上面圖片中描述的那樣描述。