18

我认为 Java 有短路评估,但这一行仍然抛出空指针异常:

if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {

在这种情况下perfectAgentnull,所以我只希望整个表达式返回false,但我的应用程序仍然在这条线上崩溃,并出现 NullPointerException。

编辑,一般回应:

由于perfectAgentis null,不应该执行右边的任何内容&&,因为表达式不可能为真。更重要的是,它不可能执行,perfectAgent.getAddress()因为perfectAgent它不包含有效的引用(它是 null 和 all)。我正在尝试使用短路评估来不必在单独的语句中检查 null,因为这会使逻辑更加草率。

编辑 2(或者,我是个白痴):是的,就像生活中的许多事情一样,你在向世界宣布你是个白痴之后就会立即找到答案。在这种情况下,我在执行其他操作时关闭了 Eclipse 的自动构建并且没有重新打开它,因此我正在调试与我的源代码不匹配的类文件。

4

7 回答 7

10

如果perfectAgent确实为 null,则该代码不会引发异常(至少假设没有奇怪的线程处理,在表达式的中途将其从非 null 更改为 null)。如果你能制作一个简短但完整的程序来证明它这样做,我会非常震惊。

所以是的,你的直觉是正确的——这不应该是个问题。在别处寻找原因。我强烈怀疑这实际上perfectAgent 并不为空,并且您在该代码中遇到了可能导致异常的任何其他情况。

我建议您尝试将那段代码提取成一个简短但完整的示例 - 如果您可以这样做,我会吃掉我的隐喻帽子;如果没有,您希望在尝试提取时发现问题。

是什么让你认为那perfectAgent真的空的?尝试在它之前插入此代码:

if (perfectAgent == null)
{
    System.out.println("Yup, it's null");
}

另一个非常非常渺茫的可能性是您遇到了 JIT 错误——但我非常怀疑。

于 2009-11-29T21:21:49.140 回答
7

Java确实有短路评估。也许entrynull这样entry.getKey()导致的NullPointerException。另一种可能性是getAddress()返回nullNullPointerException在某处发生(如果它比简单的return语句更复杂)。

编辑:我在您声明的地方看到了您的编辑:

更重要的是,不可能执行perfectAgent.getAddress()...

但是如果perfectAgent.getAddress() 成功执行并返回 null怎么办?明白了吗...

于 2009-11-29T21:15:17.093 回答
6

高级调试课程 #1:

如果您遇到看似不可能的错误(例如,与您对 Java 的了解相矛盾的错误),请执行以下操作:

  • 查阅有信誉的教科书(或者更好的是相关标准),以确认您的理解没有缺陷。(在这种情况下,你的理解是正确的,任何一本像样的教科书都会在一分钟内证实这一点。)

  • 检查所有可能导致不可能错误的愚蠢事情。诸如不保存文件、不进行完整构建、运行旧/陈旧版本的应用程序、位于错误目录等的事情。

总之,学会多怀疑自己。

于 2009-11-29T23:24:30.097 回答
2

您确保它perfectAgent不为空,因此一个或多个perfectAgent.getAddress()orentryentry.getKey()必须为空。或者 getAddress() 或 getKey() 在他们的实现中遇到了 NPE。

要调试这类事情,首先查看堆栈跟踪以确定位置。这将告诉您它是否发生在 getAddress() 或 getKey() 或调用它们的粘贴代码片段中。接下来,如果它在此代码段中,请在 if 之前添加一些代码以测试哪个为空。您可以使用旧的 System.err.println() 或assertions。(如果您使用断言,请务必使用 java 命令的 -enableassertions 标志启用它们。)

更新:所以我的解释结果是错误的......这个问题提出了两个相互矛盾的事实(这条线上有一个 NPE,但应该发生短路),我自动假设第一个事实是真的,第二个是假的事实上,这是一个完全不同的问题,完全是由于关闭了 Eclipse 中的自动构建。呸!在调试“不可能”的事情时,从根本上持怀疑态度是有帮助的。

于 2009-11-29T21:15:12.803 回答
1

除了 perfectAgent 之外,还有三个可能为 null 的引用:

  • 完美代理.getAddress()
  • 入口
  • entry.getKey()

分解语句或在调试器中运行它。

于 2009-11-29T21:17:38.930 回答
1

大谜团。我复制了您的代码行并使用perfectAgent == null,entry == nullentry.getKey() == null它们的组合进行了测试:我的测试台中没有 NPE (Java 1.6)。

不管它是什么烦人的错误,我怀疑它与短路评估有关。如果是这条线导致 NPE,据我所知,perfectAgent 不为空。祝你好运 - 一旦你发现它,就向我们展示它:)

于 2009-11-29T21:45:47.393 回答
0

尝试像这样格式化您的代码:

if( 
  (perfectAgent != null) 
  && (
      perfectAgent.getAddress()
      .equals(
       entry.getKey()
      )
     ) 
  ) {

它应该为您提供更好的堆栈跟踪行条目。

于 2009-11-29T21:54:55.503 回答