Java运算符优先混淆&&和++

时间:2013-12-28 10:58:47

标签: java operators operator-precedence

&&是一个从左到右计算的短路运算符,因此如果&&运算符左侧的操作数被评估为false,则评估继续。但我希望在++之前评估&&,因为它有higher precedence和(来自链接):

  

优先级较高的运算符在优先级相对较低的运算符之前进行求值。

在这种情况下,为什么count在此代码的第三行没有增加?

int mask = 2;
int count = 0;
if( !(mask > 1) && ++count > 1) { mask += 100; }
System.out.println(mask + " " + count);

5 个答案:

答案 0 :(得分:6)

不,表达式的计算方式是从左到右,同时考虑运算符优先级。因此,一旦进入a && ba就会变为假,b将不再评估。

JLS §15.23. Conditional-And Operator &&说:

  

条件和运算符&&类似于&(第15.22.2节),但仅当其左侧操作数的值为真时才计算其右侧操作数。


以下是对其工作原理的详细分步评估:

这是因为,当您将表达式解析为人类时,首先从最低优先级运算符开始。在这种情况下,&&的优先级低于++

++a < 0 && foo
        ^^
       start

为了计算&&的结果,您应该知道左操作数:

++a < 0 && ++b
^^^^^^^
so compute this

现在,当您想知道++a < 0的结果时,请先查看最低优先级运算符,即<

++a < 0
    ^
   evaluate this

为了做到这一点,你需要左右操作数。所以计算它们:

++a
0

这是++a增加的时刻。

所以,现在我们处于最底层。让我们回到顶端:

false && foo

这就是&amp;&amp;&amp;是短路进来。左操作数是假的,因此不再评估右操作数表达式foo。哪个成了:

false

没有评估右操作数。

答案 1 :(得分:4)

编辑:我错过了问题的重点。有关短路评估的半详细说明,请参见修订版。

逻辑AND和逻辑OR运算符的每个操作数是一个单独的表达式,因此,独立处理(根据正确的运算符优先级给定自己的运算符顺序进行求值)。

因此,虽然++++count > 1的优先级最高,但表达式从未被评估过(因为短路)。

答案 2 :(得分:4)

您似乎对短路评估说明不满意。为什么优先权在这里不重要?

想象一下这段代码:

if( !(mask > 1) && Increment(count) > 1)

函数应用程序(即通过编写括号调用函数)是最高优先级,但函数调用永远不会发生。如果短路评估允许优先考虑,那么它根本不会起作用。

要扩展一点 - ++, - 等运算符都映射到函数调用。但是,编译器需要了解它们绑定的顺序。这不是评估的顺序。

所以a + b * c并不意味着锻炼b * c然后是总和。这仅表示add( a, multiply(b, c))评价顺序与&amp;&amp; (虽然不在我的例子中),让程序员更容易编写快速代码。

答案 3 :(得分:1)

为避免混淆,请回忆一下

if (a && b) {
    // do something
}

在语义上与:

相同
if (a) {
    if (b) {
         // do something
    }
}

显然,如果a评估为false,则永远不会看到术语b。特别是,那里的增量opertor将不会执行。

通过回顾这种扩展,行为应该更容易理解。最好将&&视为上述嵌套if语句的快捷方式。 (如果有else语句,你还需要添加两个else代码的副本,所以这并不容易。)

更“精确”的表示是使用条件方法:

boolean condition() {
    if (!a) return false;
    if (!b) return false;
    return true;
}

如果b已经返回false,则永远不会评估a

答案 4 :(得分:0)

  

if(!(mask&gt; 1)&amp;&amp; ++ count&gt; 1){mask + = 100; }

此行表示的是: !(2>1)!(true)false

&&左侧是假的,它不会进一步检查右侧

所以count不会增加。