Throwable 提供三個重載方法將堆棧信息輸出到不同目標:
printStackTrace() → 標準錯誤流 (System.err)printStackTrace(PrintStream s) → 指定輸出流printStackTrace(PrintWriter s) → 指定寫入器若異常未被捕獲並拋出到主線程,JVM 會自動調用 printStackTrace() 並終止程序。
java.lang.NullPointerException
at MyClass.mash(MyClass.java:9)
at MyClass.crunch(MyClass.java:6)
at MyClass.main(MyClass.java:3)
toString() 返回的異常描述public class StackTraceDemo {
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 StackTraceDemo.f(StackTraceDemo.java:3)
at StackTraceDemo.g(StackTraceDemo.java:6)
at StackTraceDemo.main(StackTraceDemo.java:10)
清晰展示調用鏈:f → g → main。
返回 StackTraceElement[],每個元素對應一個棧幀,便於日誌分析、監控上報。
catch (Exception e) {
e.printStackTrace();
System.out.println("------------------------------");
for (StackTraceElement elem : e.getStackTrace()) {
System.out.println(elem); // 直接打印元素 toString()
}
}
輸出與 printStackTrace() 幀信息一致,但無異常描述首行。
本地方法,將當前調用棧填充到異常對象,返回該異常對象本身(非新建)。
| 操作 | 異常類型 | 堆棧信息 |
|---|---|---|
throw (Exception) e.fillInStackTrace() | 保持原類型 (如 NullPointerException) | 新棧頂為 fillInStackTrace() 調用處,原棧信息丟失 |
throw new Exception() | 新類型 (Exception) | 新棧頂為 throw 處,原異常信息完全丟失 |
public class FillInStackTraceDemo {
public static void main(String[] args) throws Exception { test1(); }
static void test1() throws Exception {
try { test2(); }
catch (NullPointerException ex) {
// 情況1:重置棧
throw (Exception) ex.fillInStackTrace();
// 情況2:拋出新異常
// throw new Exception();
}
}
static void test2() { test3(); }
static void test3() { throw new NullPointerException("str is null"); }
}
情況1輸出:
Exception in thread "main" java.lang.NullPointerException: str is null
at FillInStackTraceDemo.test1(FillInStackTraceDemo.java:20)
at FillInStackTraceDemo.main(FillInStackTraceDemo.java:13)
異常類型保持 NullPointerException,但棧頂變為 test1 行 20(fillInStackTrace() 處)。
throw e; 或 throw new RuntimeException("msg", e);(鏈式異常)logger.error("msg", e) 自動記錄完整堆棧,而非手動 e.printStackTrace()throw new BizException("業務失敗", originalException);深入理解堆棧機制,能顯著提升問題定位效率,是 Java 開發者必備內功。