为什么这个if语句没有短路?

3

我目前正在修复别人的Java代码中的一个错误,但我无法解释这个错误。涉及到的代码是下面的if语句:

if (locked && DEBUG_ENABLED
    && owner != null 
    && (owner.equals(playerName) || subowner.equals(playerName))
    && handleCommand(playerName, message)) {
    ....
 } else {
    ....
 }

DEBUG_ENABLED 被初始化为 private static boolean DEBUG_ENABLED = false;,而 handleCommand 函数的运作方式如下:

public boolean handleCommand(String name, String msg) {
    if(msg.equals("Command1")) {
        ....
    } else if(msg.equals("Command2")) {
        ....
    } ....
    } else {    // No matching command
        return false;
    }
    return true;
}

我困惑的是,尽管DEBUG_ENABLED被设置为false,代码仍然调用并执行handleCommand函数。我一直认为这不应该发生,因为应该会短路。
if语句本身总体上仍然被评估为false,因为只有第一个片段中else块内的代码被执行。
那么,为什么这个if语句会表现出这样的行为呢?它是否未能实现短路,还是我对原则的理解有误,或者这段代码完全有其他问题?(除了缺少对subowner的空值检查之外,该检查在此部分之外完成。)

对我来说它是短路。你用的是哪个Java版本?并且有没有可能DEBUG_ENABLEDtrue - Sotirios Delimanolis
请描述您运行代码的情况,以及您如何确切地知道它没有短路。 - Andrew Ring
我也遇到了短路问题,你确定 DEBUG_ENABLED == false 是100%正确的吗? - BackSlash
“||” 的意思是,如果 subowner.equals 返回 true,仍然必须检查 handleCommand。由于有一个 OR 子句,如果一侧为 false,则仍必须检查另一侧。DEBUG_ENABLED 使 || 左侧为 false,但右侧仍可能为 true。 - David Schwartz
哇,回应非常迅速。我们使用的是1.6版本。至于不短路的问题,如果在handleCommand函数中找到匹配项,则会显示一些文本或执行某些操作。每次测试时都可以看到这些操作,以及第一个代码段中else部分的操作。(如果if语句评估为true,则不会显示任何执行的操作。) - user2757672
David,我认为括号()||隔离开来,并且通用条件是一系列的&&。这个假设对吗? - user2757672
1个回答

1

不可能发生 && 运算符没有短路的情况。也许你使用了 &?如果不是这样,那么说明你做出了一些错误的假设,即在最后一个条件之前的先前条件都为 false。


第一个片段是代码的直接副本,初始化也是如此。我已经检查了DEBUG_ENABLED是否在代码的任何其他地方被修改或本地声明,但情况并非如此。第二个片段已经被修改,但只是为了缩短长度,同时传达思想。 - user2757672
@user2757672 你可以直接在代码中的条件语句上或之前设置断点,验证每个条件是否都为false吗? - plalx
我可以确认 DEBUG_ENABLED 是 false。然而,你建议检查每个条件以及如果它们是 false 会发生什么,这很有趣。也许这会告诉我是什么导致了这个问题。 - user2757672
@user2757672,如果在最后一个条件之前有一个条件评估为false并且运算符不短路,则解释器存在严重问题。请自行测试,if (false && true && someFunction()) {} - plalx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接