为什么Throwable.getMessage()偶尔会返回null



我有一个方法,有时会抛出异常:

this.items[index] = element;

我有一个单元测试,它断言应该抛出的异常实际上已经抛出:

try
{
    doSomethingWithIndex(-1);
    Assert.fail("should cause exception");
}
catch (IndexOutOfBoundsException expected)
{
    Assert.assertNotNull(expected.getMessage());
}

此测试作为连续构建的一部分运行,有时会失败,因为getMessage()实际上返回null。为什么会发生这种情况?我的代码永远不会抛出带有null消息的异常。

编辑

我最初的代码示例具有误导性,抛出的异常实际上来自于直接索引数组。不过,我可以使用自定义抛出的异常来重现相同的行为。

我添加了建议的代码:

catch (IndexOutOfBoundsException expected)
{
    if (expected.getMessage() == null)
    {
        expected.printStackTrace();
    }
    Assert.assertNotNull(expected.getMessage());
}

控制台输出除了原因之外,还缺少堆栈跟踪。以下是完整的输出:

java.lang.ArrayIndexOutOfBoundsException

找到了类似问题的答案。

JIT编译器将在某些异常中优化掉堆栈跟踪,如果它们发生得足够多的话。

JVM标志-XX:-OmitStackTraceInFastThrow防止了这种行为,并且似乎修复了闪烁的单元测试。

当异常具有null消息时,尝试打印异常的堆栈跟踪。可能是其他代码抛出的,就像您实际访问过去的数组长度一样。

您写道:"我的代码永远不会抛出带有空消息的异常"

你在第三方图书馆吗?我认为标准的java代码从来不会抛出像上面这样的异常,但一些pourly编码的jar…:)

最新更新