这个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()) {