Java异常的堆栈轨迹

StackTrace(堆栈轨迹)

最近看到异常捕获这部分内容,发现有一个以前没见过的名词:StackTrace。

那到底什么是堆栈轨迹呢?

堆栈轨迹(stack trace) 是一个方法调用过程的列表, 它包含了程序执行过程中方法调用的特定位置。

在Java.lang.Throwable中,是这样描述StackTrace的:

 /**
     * The stack trace, as returned by {@link #getStackTrace()}.
     *
     * The field is initialized to a zero-length array.  A {@code
     * null} value of this field indicates subsequent calls to {@link
     * #setStackTrace(StackTraceElement[])} and {@link
     * #fillInStackTrace()} will be no-ops.
     *
     * @serial
     * @since 1.4
     */
    private StackTraceElement[] stackTrace = UNASSIGNED_STACK;

由此我们可以知道:

  1. StackTracegetStackTrace() 方法的返回值,它是StackTraceElement 对象的一个数组。
  2. StackTrace字段的空值表示此后对setStackTrace(StackTraceElement[])fillInStackTrace() 的调用将不会被执行任何操作(StackTrace 是一个方法调用过程的列表,若为空则说明没有发生方法调用)。

StackTraceElement 类含有能够获得文件名和当前执行的代码行号的方法,同时,还含有能够获得类名和方法名的方法。toString方法将产生一个格式化的字符串,其中包含所获得的信息。

private StackTraceElement[] stackTrace = UNASSIGNED_STACK;

其中UNASSIGNED_STACK 是空栈的共享值,即length=0StackTraceElement 对象数组,用它来初始化StackTrace。

/**
     * A shared value for an empty stack.
     */
private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];

PrintStackTrace()方法:

捕获到异常时,往往需要进行一些处理。比较简单直接的方式就是打印异常栈轨迹Stack Trace。

public void printStackTrace() {
        printStackTrace(System.err);
}

public void printStackTrace(PrintStream s) {
        printStackTrace(new WrappedPrintStream(s));
}

public void printStackTrace(PrintStream s) {
        printStackTrace(new WrappedPrintStream(s));
}

private void printEnclosedStackTrace(PrintStreamOrWriter s,
                                         StackTraceElement[] enclosingTrace,
                                         String caption,
                                         String prefix,
                                         Set<Throwable> dejaVu)
public void printStackTrace(PrintWriter s)

这个方法会将Throwable对象的栈轨迹信息打印到标准错误输出流上。例:

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)

版权声明:本文为morphy0407原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。