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 = 4rear = 4。条件frnt &lt; 5 有效,但rear &gt;= 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 &gt;= 5。为了获得正确的行为,请将条件更改为:frnt &lt; 5 &amp;&amp; rear &gt;= 4,或更明确地说,frnt &lt;= 4 &amp;&amp; rear &gt;= 4

【讨论】:

【参考方案3】:

frnt---- rear ---------- frnt &lt; 5 &amp;&amp; rear &gt;= 5

0-----------8------- true &amp;&amp; true -&gt; true

1-----------7------- true &amp;&amp; true -&gt; true

2-----------6------- true &amp;&amp; true -&gt; true

3-----------5------- true &amp;&amp; true -&gt; true

4------------4------- true &amp;&amp; false -&gt; false

一切都是正确的,4 次迭代就是这样。

我认为您误解了短路原理。在 && 运算符的情况下,短路原理如下:

由于A && B 运算的结果是true,只有当两个操作数都是true,然后在评估操作数A并发现它是false时,不需要评估和检查的值操作数 B。如果操作数 A 为 true,则始终计算操作数 B。因此,在您的情况下,当循环中断时检查操作数 A 是 4 &lt; 5 并且操作数 B 是 4 &gt;= 5。因此,由于操作数 A 是 true,因此必须对操作数 B 进行评估和检查,并且这种情况不是短路,因为两个操作数都被评估了。如果操作数 A 是 false 并且未评估操作数 B,则短路情况将是一种情况。

【讨论】:

以上是关于Java短路混淆的主要内容,如果未能解决你的问题,请参考以下文章

java proguard混淆示例和结果

java proguard混淆示例和结果

Android 代码混淆

Android-android 怎么实现只混淆自己的代码,而不混淆第3方jar包

maven混淆Java代码

Flink 代码混淆