Java短路评估

时间:2009-11-29 21:04:54

标签: java logical-operators short-circuiting

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

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

在这种情况下,perfectAgentnull,所以我只想让整个表达式返回false,但我的应用程序仍然在这行上发生NullPointerException崩溃。

编辑,一般回复:

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

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

7 个答案:

答案 0 :(得分:10)

如果perfectAgent真的为null,那么代码将不会抛出异常(至少假设没有奇怪的线程发生,将其从非null更改为null通过表达的一半)。如果你能够制作一个简短但完整的程序来证明它这样做,我会感到非常震惊。

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

我建议你尝试将这段代码提取到一个简短但完整的例子中 - 如果你能这样做,我会吃掉我的隐喻帽子;如果没有,你会在尝试提取时发现问题。

是什么让您认为perfectAgent确实 为空?尝试在它之前插入此代码:

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

另一个非常非常微小的可能性是你遇到了一个JIT错误 - 但我非常怀疑它。

答案 1 :(得分:7)

Java 进行短路评估。可能entrynull,因此entry.getKey()导致NullPointerException。另一种可能性是getAddress()返回null或在某处发生NullPointerException(如果它比简单的return语句更复杂)。

编辑:我看到你的编辑声明了这一点:

  

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

是不可能的

但是如果perfectAgent.getAddress() 成功执行并且返回 null怎么办?看看我的意思......

答案 2 :(得分:6)

高级调试课程#1:

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

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

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

总之,要学会更多地怀疑自己。

答案 3 :(得分:2)

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

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

更新:所以我的解释被证明是错的......这个问题提出了两个相互矛盾的事实(这条线上有一个NPE,但短路应该发生了)我自动假设第一个事实是真的而第二个是假的,实际上它完全是由于关闭Eclipse中的自动构建而出现的另一个问题。咄!在调试“不可能”的事情时,它会有助于产生根本的怀疑。

答案 4 :(得分:1)

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

  • perfectAgent.getAddress()
  • 输入
  • entry.getKey()

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

答案 5 :(得分:1)

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

无论是什么烦人的错误,我都怀疑它与短路评估有关。如果是这条线导致NPE,那么,就我所知,perfectAgent不是空的。祝你好运 - 一旦你抓住它就把它告诉我们:)

答案 6 :(得分:0)

尝试格式化您的代码:

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

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