什么是Java堆栈跟踪,如何使用它来调试应用程序错误?


什么是Java堆栈跟踪,如何使用它来调试应用程序错误?

简单来说,堆栈跟踪是应用程序在抛出异常时处于中间的方法调用的列表。

简单的例子

通过问题中给出的示例,我们可以确切地确定应用程序中抛出异常的位置。我们来看看堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

这是一个非常简单的堆栈跟踪。如果我们从“at ...”列表的开头开始,我们可以告诉我们的错误发生在哪里。我们正在寻找的是作为我们应用程序一部分的最顶层方法调用。在这种情况下,它是:

at com.example.myproject.Book.getTitle(Book.java:16)

要调试这个,我们可以打开Book.java并查看一行16,即:

15   public String getTitle() {
16      System.out.println(title.toString());
17      return title;
18   }

这表明上述代码中存在某些内容(可能title)null。

一系列例外情况的示例

有时,应用程序将捕获异常并将其作为另一个异常的原因重新抛出。这通常看起来像:

34   public void getBookIds(int id) {
35      try {
36         book.getId(id);    // this method it throws a NullPointerException on line 22
37      } catch (NullPointerException e) {
38         throw new IllegalStateException("A book has a null property", e)
39      }
40   }

这可能会为您提供如下所示的堆栈跟踪:

Exception in thread "main" java.lang.IllegalStateException: A book has a null property
        at com.example.myproject.Author.getBookIds(Author.java:38)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
Caused by: java.lang.NullPointerException
        at com.example.myproject.Book.getId(Book.java:22)
        at com.example.myproject.Author.getBookIds(Author.java:36)
        ... 1 more

这个有什么不同的是“引起的”。有时,异常会有多个“由...引起”部分。对于这些,您通常希望找到“根本原因”,它将是堆栈跟踪中最低的“由...引起”部分之一。在我们的例子中,它是:

Caused by: java.lang.NullPointerException <-- root cause
        at com.example.myproject.Book.getId(Book.java:22) <-- important line

同样,对于此例外,我们会想看看行22的Book.java,看看有什么可能导致NullPointerException这里。