Java短路混淆
Posted
技术标签:
【中文标题】Java短路混淆【英文标题】:Java short circuit confusion 【发布时间】:2017-10-04 11:04:18 【问题描述】:此代码在 for 循环条件中使用 &&。它迭代 4 次,得到答案“sum = 20”。我认为它会迭代 5 次,因为 && 条件的左侧为真,当右侧变为假时结束循环。
基本上我的问题是为什么它迭代 4 次而不是 5 次,使“总和 = 30”?谢谢
`int[] lst = 1,2,3,4,5,4,3,2,1;
int sum = 0;
for (int frnt = 0, rear = lst.length - 1;
frnt < 5 && rear >= 5; frnt++, rear--)
sum = sum + lst[frnt] + lst[rear];
System.out.println("frnt: " + frnt);
System.out.println("rear: " + rear);
System.out.println();
System.out.print(sum);`
【问题讨论】:
&& 是and,这意味着两个条件都必须为真,任何一个为假都会导致条件失败。 这个和那个必须都是真的。 我认为“两个条件都必须为真”是针对 &。 && 是短路“和”,这意味着如果第一个为真,则不会评估第二个。反正我就是这么学的。 这对 || 来说是正确的。 (要么)。对于 &&,短路意味着如果第一个为假,则不会评估第二个,因为整个表达式已经为假。 谢谢@clcto!现在我明白了。 谢谢@KenWhite 【参考方案1】:只有当整个表达式的值已知时才会发生短路。
对于逻辑与运算符 (&&),如果左侧已经为假,那么右侧的计算结果无关紧要,因为整个表达式已经为假。如果左侧为真,则右侧的值决定表达式的值。由于在评估之前它是未知的,因此必须对其进行评估。
对于逻辑或运算符 (||),反之亦然。如果表达式的左侧为真,那么无论右侧是什么,表达式都为真,因此不对右侧求值。如果左侧为假,则表达式的值取决于右侧,因此必须对其求值。
【讨论】:
啊...我把这两个想法混为一谈了。非常感谢!【参考方案2】:问题源于for
条件。在循环的最后一次迭代中,frnt = 4
和 rear = 4
。条件frnt < 5
有效,但rear >= 5
为假,使整个表达式为假,从而中断循环。每次迭代后的变量见下文(请注意,该表显示了每次循环体运行并修改变量后的变量)。
frnt rear
before loop: 0 8
iteration 1: 1 7
iteration 2: 2 6
iteration 3: 3 5
iteration 4: 4 4 <---- Loop breaks after this
两个计数器在 4 处相遇,但条件指定 rear >= 5
。为了获得正确的行为,请将条件更改为:frnt < 5 && rear >= 4
,或更明确地说,frnt <= 4 && rear >= 4
【讨论】:
【参考方案3】:frnt
---- rear
---------- frnt < 5 && rear >= 5
0
-----------8
------- true && true -> true
1
-----------7
------- true && true -> true
2
-----------6
------- true && true -> true
3
-----------5
------- true && true -> true
4
------------4
------- true && false -> false
一切都是正确的,4 次迭代就是这样。
我认为您误解了短路原理。在 && 运算符的情况下,短路原理如下:
由于A && B 运算的结果是true
,只有当两个操作数都是true
,然后在评估操作数A并发现它是false
时,不需要评估和检查的值操作数 B。如果操作数 A 为 true
,则始终计算操作数 B。因此,在您的情况下,当循环中断时检查操作数 A 是 4 < 5
并且操作数 B 是 4 >= 5
。因此,由于操作数 A 是 true
,因此必须对操作数 B 进行评估和检查,并且这种情况不是短路,因为两个操作数都被评估了。如果操作数 A 是 false
并且未评估操作数 B,则短路情况将是一种情况。
【讨论】:
以上是关于Java短路混淆的主要内容,如果未能解决你的问题,请参考以下文章