Java逻辑运算符(&&,||)的短路机制

16

当我阅读同事的Java代码时,我遇到了一堆if/else语句。在这些语句中,有几个&&和||运算符在没有括号的情况下互相竞争。我将这些语句简化为:

if (true || true && false)
  return true;
else
  return false;

你认为结果会是什么?老实说,我以为会是false,但短路似乎不像我想象的那样工作。在这种情况下,结果是true。当短路机制发现紧接着||true时,它似乎将整个表达式视为true

但在反转的表达式中,结果是什么?

if (false && true || true)
  return true;
else
  return false;

如果我们按照相同的逻辑,结果应该是假的。第一个布尔值是false,紧接着是&&,但结果再次是true。这对我来说是有道理的,但它似乎与我们之前的实验不兼容。

所以这是我的理论:

如果我们找到一个跟随||true,那么它就是true,无论之后可能出现什么,即使后面有一长串其他逻辑运算符。但如果我们找到一个跟随&&false,它只会短路下一个元素,而不是整个语句。

这是我的问题:

我是对的吗?这对我来说似乎有点傻。是truefalse更强吗?


19
如现有答案所述,“&&”的优先级高于“||”,具体请参考以下链接:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html - Max Fichtelmann
1
无论如何,您应该要求您的同事在这种情况下编写括号,以避免在有人向此代码添加新条件时可能发生的错误! - Joel
11
短路运算永远不会改变布尔表达式的结果。短路运算所做的唯一事情就是避免执行表达式的其余部分。 - dimo414
2
@Jägermeister,公平地说,如果提问者询问代码是否应该这样编写,那么这个问题可能会被关闭,因为它主要是基于观点的。 - Dancrumb
8
重点不在于短路,而在于运算符优先级。 - njzk2
显示剩余4条评论
6个回答

58
这是因为
if (false && true || true)

等价于(&& 具有更高的优先级
if ((false && true) || true)

这是。
if (false || true)

这段文字的翻译如下:

它是...true

注意:在表达式true || true && false中,部分true && false被称为死代码,因为它不会影响评估的最终结果,因为true || anything总是true


值得一提的是,存在可以应用于布尔值的&|运算符,它们很像&&||,只是它们不会短路。这意味着如果您有以下表达式:
if (someMethod() & anotherMethod())

如果 someMethod 返回 falseanotherMethod 仍然会被执行!但是 if 不会被执行,因为最终结果将被评估为 false

4
好的,它的运作方式类似于“1 + 1 * 2 = 3”。我不知道&&和||运算符存在这样的优先级。非常感谢 :) - Jason Berger
5
@JasonBerger 的表达式 false && true || true 非常类似于 0 * 1 + 1,有关详细信息,请参阅布尔代数 - schnittstabil
5
不要鼓励编写像这样的代码:if (someMethod() & anotherMethod())。应该将其拆分为多行。 - BlueRaja - Danny Pflughoeft
6
如果你想要同时执行这两种方法(可能是因为它们有副作用),那么它们不应该在一个 if 语句中。这样只会令人困惑。 - Chris Hayes
1
&符号被设计用于执行位运算,而不是在if语句中链接函数...这只是一个副作用。 - rr-
显示剩余10条评论

15

&& 的操作优先级高于 ||,因此它胜出。


9
根据Java教程&&的优先级高于|| 因此,true || true && false会被解释为true || (true && false)false && true || true会被解释为(false && true) || true 这两种情况的输出结果都是true

5

对于 &&:

false && ... => false

对于 ||:

true || ... => true.

&& 的优先级高于 ||

更多信息请参见:Java 中的运算符优先级


3

1
我看到你的想法,但在操作括号之前最好先了解语言规范。我认识一些程序员,他们甚至会将重要的部分(如运算符优先级)贴在墙上。
第二部分是要知道你的修改是否会让工作场所的其他人理解有意义;如果去掉括号会损害其他人对代码的理解,那么这可能会对项目产生不利影响。
通常优化器会为您处理它,所以如果有疑问,请保留括号。

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