我一直在阅读我使用的API实现的源代码,并偶然发现了这部分代码:
if (condition1 & condition2 && (condition3 || condition4))
条件1和2不会调用任何方法或执行任何操作,而3和4则不会。我想知道为什么程序员决定不使用短路&&用于比较前两个语句的运算符,因为我看不到使用它的任何好处(另外一个条件要检查,其他两个条件实际上对程序的其他部分有任何影响仍然是短路的。)
答案 0 :(得分:5)
我能想到的唯一理由就是避免与&&
结合的分支。你可以在字节码中看到这个:
a & b
:
ILOAD 1
ILOAD 2
IAND
a && b
:
ILOAD 1
IFEQ L3
ILOAD 2
IFEQ L3
ICONST_1
GOTO L4
当然,有些情况下&
略微优于&&
(特别是当你几乎可以确定第一个条件为真时)。然而,&&
通常是首选,因为1)这种情况很少见; 2)在大多数情况下,性能差异完全可以忽略不计。
答案 1 :(得分:3)
在不知道condition1
的频率是多少的情况下,使用&&
会更好(效率更高一些),因为不需要检查第二个操作数condition2
如果condition1
为false,则可能会保存一些CPU指令。
如果统计上condition1
经常是真的,那么使用&
可能更有效,因为(通常不必要的)短路检查会被跳过。
在java中,你可以使用bitwise和&
和布尔操作数来给出一个布尔结果,但是
唯一一次使用&
和&&
之间的功能区别是在第二个操作数中调用代码,例如:
condition1 & <some code giving a boolean> // exdcutes "some code" regardless of condition1
condition1 && <some code giving a boolean> // only executes "some code" if condition1 is true
我会考虑使用&
始终使<some code giving a boolean>
处于“副作用”区域,并且不值得引起混淆。
答案 2 :(得分:1)
实际上有一个原因是&amp;考虑到已经讨论过的关于&amp; amp;&amp; amp; amp; amp; amp;&amp; amp;如果条件是布尔值,则同样快。
在Java语言规范中,§15.7。
Java编程语言保证了操作数 运算符似乎在特定的评估顺序中进行评估, 即,从左到右。
建议代码不要严格依赖此规范。 当每个表达式最多包含一侧时,代码通常更清晰 效果,作为最外层的操作,当代码不依赖时 究竟哪个例外由于从左到右而产生 评价表达。
如果您查看order of operations,您会看到&amp;来到&amp;&amp ;.因此,这一陈述坚持明确评估顺序的原则,而不依赖于从左到右的Java评估。如果condition3或condition4调用修改方法,这个选择将特别重要 - 尽管这将是错误的编码。