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

为什么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; } 

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

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

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

 if (func1() || (func2() && func3())) 

在func1返回后,它变为:

 if (true || (func2() && func3())) 

在评估短路后,它变为:

 if (true) 

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

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

所以你表达了

 (A || B && C) 

是的

 (T || F && F) 

被包括在内

 (T || (F && F)) 

因为优先规则。

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

如果你已经括起来((A || B) && C)那么它将评估为假。

编辑

另一种方式,如其他海报所述,是使用“|” 和“&”而不是“||” 和“&&”因为它阻止表达式的快捷方式。 但是,由于优先规则,最终结果仍然是相同的。

Java短路布尔表达式。 这意味着,一旦执行了func1()并返回true ,那么该布尔值的其余部分无关紧要,因为您使用的是or运算符。 无论func2() && func3()计算结果如何,整个表达式的计算结果为true 。 因此,Java甚至不打算评估func2()func3()

您正在使用快捷方式运算符|| 和&&。 如果已定义结果,则这些运算符不会执行表达式的其余部分。 对于|| 这意味着如果第一个表达式为真,对于&&,如果第一个表达式为假。

如果要执行表达式的所有部分,请使用| 和&而是,这不是捷径。

Java使用Lazy评估。

由于Func1总是返回true,因此整个表达式必须为true,因此它会快速删除表达式的其余部分。

 true || (???) 

 false && (???) 

永远是捷径。

要关闭快捷方式评估,请使用| 和&而不是|| 和&&

我们可以用它来达到很好的效果:

 String s; if (s != null && !s.equals("")) ... 

这意味着如果s为null,我们甚至不必尝试调用s.equals,并且我们最终不会抛出NullPointerException

简答: 短路评估

因为func1()yelds为true所以不需要继续评估,因为它总是如此

如果函数1总是返回true,那么Java不需要计算表达式的其余部分来确定整个表达式是真的。

如果您希望执行所有function,可以删除快捷方式

 if (func1() | func2() & func3()) {