Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 逻辑AND运算符在这里有用吗?_Java - Fatal编程技术网

Java 逻辑AND运算符在这里有用吗?

Java 逻辑AND运算符在这里有用吗?,java,Java,我一直在阅读我使用的API实现的源代码,偶然发现了这部分代码: if (condition1 & condition2 && (condition3 || condition4)) 条件1和2不会调用任何方法或执行任何操作,而条件3和4会调用任何方法或执行任何操作。我想知道为什么程序员决定不使用short-circuit&&运算符来比较前两条语句,因为我看不出使用它有什么好处(还有一个条件需要检查,另外两个可能对程序的其他部分产生影响的条件仍然是short-circui

我一直在阅读我使用的API实现的源代码,偶然发现了这部分代码:

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短路的细节。我不是想说作者所做的是每个人都应该做的。