我已经有我们的Java代码的实例捕捉一个NullPointerException,但当我试图记录StackTrace(基本上最终调用Throwable.printStackTrace()),我得到的是:

java.lang.NullPointerException

有人遇到过吗?我试着在谷歌上搜索“java空指针空堆栈跟踪”,但没有遇到这样的东西。


当前回答

当您在项目中使用AspectJ时,可能会发生某些方面隐藏其堆栈跟踪的部分。例如,今天我有:

java.lang.NullPointerException:
  at com.company.product.MyTest.test(MyTest.java:37)

这个堆栈跟踪是在通过Maven的surefire运行测试时打印的。

另一方面,当在IntelliJ中运行测试时,会打印不同的堆栈跟踪:

java.lang.NullPointerException
  at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
  at ...
  at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
  at ...
  at com.company.product.MyTest.test(MyTest.java:37)

其他回答

例外。toString不给你StackTrace,它只返回

这是一个简短的描述扔。 结果是: *该对象的类名 * ": "(冒号加空格) *调用该对象的getLocalizedMessage()方法的结果


使用异常。而不是printStackTrace来输出StackTrace。

您可能正在使用HotSpot JVM(最初由Sun Microsystems开发,后来被Oracle收购,是OpenJDK的一部分),它执行大量优化。为了获得堆栈跟踪,你需要将以下选项传递给JVM:

-XX:-OmitStackTraceInFastThrow

优化的方法是,当异常(通常是NullPointerException)第一次发生时,打印完整的堆栈跟踪,JVM记住堆栈跟踪(或者可能只是代码的位置)。当异常发生的次数足够频繁时,堆栈跟踪就不再打印了,这既是为了获得更好的性能,也是为了不让相同的堆栈跟踪充斥日志。

要了解这是如何在HotSpot JVM中实现的,请获取它的副本并搜索全局变量OmitStackTraceInFastThrow。我上次查看代码(在2019年)时,它位于graphKit.cpp文件中。

toString()只返回异常名称和可选消息。我建议你打电话

exception.printStackTrace()

要转储消息,或者如果你需要血腥的细节:

 StackTraceElement[] trace = exception.getStackTrace()

VM停止输出多次抛出的异常的堆栈跟踪。这是发生在C2编译中的优化之一。

根据OpenJDK源代码,此优化应用于以下例外情况:

nullpointerexception -ArithmeticException -ArrayIndexOutOfBoundsException -ArrayStoreException classcastexception

当您在项目中使用AspectJ时,可能会发生某些方面隐藏其堆栈跟踪的部分。例如,今天我有:

java.lang.NullPointerException:
  at com.company.product.MyTest.test(MyTest.java:37)

这个堆栈跟踪是在通过Maven的surefire运行测试时打印的。

另一方面,当在IntelliJ中运行测试时,会打印不同的堆栈跟踪:

java.lang.NullPointerException
  at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
  at ...
  at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
  at ...
  at com.company.product.MyTest.test(MyTest.java:37)