这个Java代码中的短路逻辑有什么问题?

Dra*_*orn 8 java logical-operators

为什么func3不能在下面的程序中执行?在func1之后,func2不需要得到评估但是对于func3,不应该吗?

if (func1() || func2() && func3()) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }
}

public static boolean func1() {
    System.out.println("func1");
    return true;
}

public static boolean func2() {
    System.out.println("func2");
    return false;
}

public static boolean func3() {
    System.out.println("func3");
    return false;
}
Run Code Online (Sandbox Code Playgroud)

Pow*_*ord 25

你正在使用短路或.如果第一个参数为true,则整个表达式为true.

如果我添加编译器使用的隐式括号,它可能会有所帮助

编辑:正如Chris Jester-Young所说,这实际上是因为逻辑运算符必须具有从左到右的关联性:

if (func1() || (func2() && func3()))
Run Code Online (Sandbox Code Playgroud)

在func1返回后,它变为:

if (true || (func2() && func3()))
Run Code Online (Sandbox Code Playgroud)

在评估短路后,它变为:

if (true)
Run Code Online (Sandbox Code Playgroud)

  • 为避免疑问,这是因为&&的优先级高于||.在这两种情况下,相关性都是从左到右. (13认同)
  • 我提到这个是因为否则这篇文章会导致问题,为什么(A ||(B && C))而不是((A || B)&& C). (4认同)
  • (对于夜晚来说重要的是它在这里很重要,没有关联性没有看到.IMO,表达式如`a || b && c`和`a && b || c`(这是` (a && b)|| c)令人困惑,编译器应该抱怨.) (4认同)

Dev*_*inB 6

根据优先级规则评估Java函数

因为"&&"比"||"具有更高的优先级,所以首先评估它,因为你没有任何括号来设置显式优先级

所以你表达了

(A || B && C) 
Run Code Online (Sandbox Code Playgroud)

是的

(T || F && F)
Run Code Online (Sandbox Code Playgroud)

被包括在内

(T || (F && F)) 
Run Code Online (Sandbox Code Playgroud)

因为优先规则.

由于编译器理解如果'A == true'它不需要打扰评估表达式的其余部分,它会在评估A之后停止.

如果你已经括号((A || B) && C)那么它会评估为假.

编辑

另一种方式,正如其他海报所提到的那样是使用"|" 和"&"而不是"||" 和"&&"因为这会阻止表达式的快捷方式.但是,由于优先规则,最终结果仍然是相同的.