为什么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;
}
答案 0 :(得分:25)
你正在使用短路或。如果第一个参数为true,则整个表达式为真。
如果我添加编译器使用的隐式括号
,它可能会有所帮助编辑:正如Chris Jester-Young所说,这实际上是因为逻辑运算符必须从左到右相关联:
if (func1() || (func2() && func3()))
func1返回后,它变为:
if (true || (func2() && func3()))
评估短路后,或者变为:
if (true)
答案 1 :(得分:6)
因为“&&”具有比“||”更高的优先级,它首先被评估,因为你没有任何括号来设置显式优先级
所以你表达了
(A || B && C)
是
(T || F && F)
被放在括号中
(T || (F && F))
因为优先规则。
由于编译器理解如果'A == true'它不需要打扰评估表达式的其余部分,它会在评估A后停止。
如果您已将((A || B) && C)
括起来,那么它会评估为假。
编辑
另一种方式,如其他海报所述,是使用“|”和“&”而不是“||”和“&&”因为这会阻止表达式的快捷方式。 但是,由于优先规则,最终结果仍然是相同的。
答案 2 :(得分:3)
Java短路布尔表达式。这意味着,一旦func1()
被执行并返回true
,该布尔值的其余部分无关紧要,因为您使用的是or
运算符。无论func2() && func3()
评估的是什么,整个表达式都将评估为true
。因此,Java甚至不打算评估func2()
或func3()
。
答案 3 :(得分:2)
答案 4 :(得分:2)
Java使用Lazy评估。
由于Func1总是返回true,因此整个表达式必须为true,因此它会快速删除表达式的其余部分。
true || (???)
和
false && (???)
总是快捷方式。
要关闭快捷方式评估,请使用|和&而不是||和&&
我们可以使用这个效果很好:
String s;
if (s != null && !s.equals("")) ...
意思是如果s为null,我们甚至不必尝试调用s.equals,并且我们不会最终抛出NullPointerException
答案 5 :(得分:2)
您正在使用快捷方式运算符||和&&如果已定义结果,则这些运算符不会执行表达式的其余部分。对于||这意味着如果第一个表达式为真且对于&&如果第一个表达式为假。
如果要执行表达式的所有部分,请使用|和&相反,那不是捷径。
答案 6 :(得分:1)
因为func1()yelds为true所以不需要继续评估,因为它总是正确的
答案 7 :(得分:1)
如果函数1总是返回true,那么Java不需要计算表达式的其余部分来确定整个表达式是真的。
答案 8 :(得分:0)
如果您想要执行所有功能,可以删除快捷方式
if (func1() | func2() & func3()) {