Java运算符预先混淆了&&和++

Pét*_*zon 7 java operators operator-precedence

&&从左至右评估短路操作,因此,如果在左侧的操作&&运营进行评估,以虚假的,评估应该不会继续.但我++之前应该评估&&它,因为它具有更高的优先级,并且(来自链接):

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

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

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

Mar*_*aux 6

不,表达式的计算方式从左到右,同时考虑运算符优先级.因此,一旦在 a && ba变假,b不再被评估.

JLS§15.23.条件和运算符&&说:

条件和运算符&&类似于&(§15.22.2),但只有在其左侧操作数的值为真时才计算其右侧操作数.


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

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

++a < 0 && foo
        ^^
       start
Run Code Online (Sandbox Code Playgroud)

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

++a < 0 && ++b
^^^^^^^
so compute this
Run Code Online (Sandbox Code Playgroud)

现在,当你想知道结果时++a < 0,首先看看最低优先级运算符,即<:

++a < 0
    ^
   evaluate this
Run Code Online (Sandbox Code Playgroud)

为此,您需要左右操作数.所以计算它们:

++a
0
Run Code Online (Sandbox Code Playgroud)

这是++a增加的时刻.

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

false && foo
Run Code Online (Sandbox Code Playgroud)

这就是&&短路的事实.左操作数是假的,因此foo不再评估右操作数表达式.哪个成了:

false
Run Code Online (Sandbox Code Playgroud)

没有评估右操作数.


use*_*280 5

您似乎对短路评估的解释不满意。为什么优先级在这里不重要?

想象一下这段代码:

if( !(mask > 1) && Increment(count) > 1)
Run Code Online (Sandbox Code Playgroud)

函数应用(即通过写括号来调用函数)的优先级最高,但函数调用永远不会发生。如果短路评估考虑到了优先级,那么它根本就不起作用。

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

所以a + b * c并不意味着锻炼 b * c 然后是总和。这仅意味着add( a, multiply(b, c))在 && 的情况下求值顺序有所不同(尽管在我的示例中并非如此),以便程序员更容易编写快速代码。


Tro*_*jan 4

编辑:我错过了问题的要点。请参阅短路评估的半详细说明的修订版。

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

因此, while++在 中具有最高优先级++count > 1,但该表达式甚至从未被求值(因为短路)。