Java 逻辑AND运算符在这里有用吗?
我一直在阅读我使用的API实现的源代码,偶然发现了这部分代码:Java 逻辑AND运算符在这里有用吗?,java,Java,我一直在阅读我使用的API实现的源代码,偶然发现了这部分代码: if (condition1 & condition2 && (condition3 || condition4)) 条件1和2不会调用任何方法或执行任何操作,而条件3和4会调用任何方法或执行任何操作。我想知道为什么程序员决定不使用short-circuit&&运算符来比较前两条语句,因为我看不出使用它有什么好处(还有一个条件需要检查,另外两个可能对程序的其他部分产生影响的条件仍然是short-circui
if (condition1 & condition2 && (condition3 || condition4))
条件1和2不会调用任何方法或执行任何操作,而条件3和4会调用任何方法或执行任何操作。我想知道为什么程序员决定不使用short-circuit&&运算符来比较前两条语句,因为我看不出使用它有什么好处(还有一个条件需要检查,另外两个可能对程序的其他部分产生影响的条件仍然是short-circuit) 如果统计上的
条件1
经常为真,则使用&
可能更有效,因为(通常不必要的)短路检查将被跳过
在java中,允许对布尔操作数使用按位and和&
来给出布尔结果,但是
使用&
和&
之间唯一的功能区别是在第二个操作数中调用代码,例如:
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
condition1&//exdcutes“一些代码”,而不管condition1如何
条件1&&//仅在条件1为true时执行“某些代码”
我认为使用<代码>和<代码>总是运行<代码> <代码>处于“副作用”区域,不值得它造成的混乱。
。这样做的唯一理由是避免与<代码>和< /代码>耦合的分支。您可以在字节码中看到:a&b
:
ILOAD 1
ILOAD 2
IAND
ILOAD 1
IFEQ L3
ILOAD 2
IFEQ L3
ICONST_1
GOTO L4
a&b
:
ILOAD 1
ILOAD 2
IAND
ILOAD 1
IFEQ L3
ILOAD 2
IFEQ L3
ICONST_1
GOTO L4
当然,在某些情况下,
&
的性能会略微优于&
(特别是,当您几乎确定第一个条件为真时)。然而,&&
通常是首选,因为1)这种情况很少发生,2)在大多数情况下,性能差异完全可以忽略不计 考虑到已经讨论过的一点,&如果条件是布尔的,那么它的速度也一样快,实际上有一个原因是,&运算符可能会超过&&
在Java语言规范中,§15.7
Java编程语言保证
运算符似乎按特定的求值顺序求值,
即从左到右
建议代码不要完全依赖于此规范。
当每个表达式最多包含一面时,代码通常更清晰
效果,作为其最外层的操作,并且当代码不依赖于
从左到右到底会出现哪种异常
表达式的求值
如果您检查,您将看到&出现在&&之前。因此,该语句坚持明确求值顺序的原则,而不依赖于Java从左到右求值。如果condition3或condition4调用修改方法,这个选择将特别重要——尽管这是糟糕的编码。@arshajii我也这么认为,但在Java中,
&
的操作数和if
中的表达式必须是布尔值
@Alnitak Yea,你是对的。我刚刚意识到,如果条件1和2是简单的布尔变量,&
更快,效果也一样。或者,如果它们是几乎可以肯定为真的表达式(第二个表达式的有效性不取决于第一个表达式的真实性),那么它也同样有效。@arshajii yep,两个布尔人,第一个是标志,第二个是对象标识比较。执行条件分支需要时间。把布尔值加在一起是非常便宜的。波希米亚人,我注意到@HotLicks(@HotLicks?)在上面的评论中写道&
比&
快。你说的正好相反。也许有人不同意。或者支持你的观点。就我个人而言,我认为你的回答在这种情况下是正确的,“没有好处”。从Arshajii的回答中可以清楚地看出,&
的速度更快。不是一个落选者,而是“唯一有差异的时候”可以改写为“唯一有不同行为的时候”。否则,行为是相同的,即使存在边际时间优势。@weston yeah fair call-现在说的是“功能差异”。@HotLicks只有在条件1
为真时,它才会更快。如果在第二个条件中进行身份比较检查,这是否适用?我认为这可能会慢一点。@yawkat如果您几乎确定第一个条件为true
,那么它可能适用。在任何情况下,如果没有自己的时间安排,很难判断。不管怎样,“框架”基本上都是相同的。如果在第二个条件中有条件逻辑,则可以得出两个条件的速度相同,但我很难想象第二个条件的速度会更快(假设第一个条件是真的)。如果代码的作者真的关心这一点,他可以只包含另一组括号(条件1和条件2)
。如果使用了&&
,条件仍然会按照相同的顺序进行评估,因为&&
总是从左到右进行评估。唯一可能存在可检测差异的情况是,如果第二个条件具有希望总是发生的副作用,即使第一个条件为假。是的,我想,是的nce肯定会强制进行左右评估。那么,读者是否真的更清楚它会从左到右进行评估?这是OoO的细节vs短路的细节。我不是想说作者所做的是每个人都应该做的。