如何解释这个运算符结合性?

How to explain this operator associativity?

根据this table++具有从右到左的结合性。所以,我 运行 这个代码:

int a = 5;
++a + ++a * ++a

并期望表达式为 50(因为 8 + 7 * 6,增量从右到左开始)。但是 Eclipse 会从左到右 (6 + 7 * 8) 计算表达式,并给出结果 62。我是 Java 中的这种关联性的新手,肯定遗漏了一些明显的东西。请帮助我理解这种奇怪的行为。

编辑: 感谢您的回答,但我现在还有一个问题。就是说,从@bizclop 的代码和树答案可以看出,++ 的关联性显然无关紧要。那么,对于++/--的这种关联性,是否有任何用例?

这是因为乘法运算符*比加法运算符+具有更高的优先级。

计算结果为++a + (++a * ++a) = 6 + 7 * 8

这里混淆了两种不同的东西:表达式解析和表达式求值。

让我们从表达式开始:++a + ++a * ++a。我们首先与它有什么关系?由于运算符 +* 需要两个操作数,而 ++ 需要一个,我们必须弄清楚哪个操作数对应哪个操作。这是表达式解析步骤,其中应用 precedence/associativity。

  1. ++ 具有最高的优先级,因此我们可以将表达式重写为 (++a) + (++a) * (++a)
  2. 接下来是 *,所以我们可以再次添加括号:(++a) + ((++a) * (++a))
  3. 最后我们有 +,所有优先级最低的,所以为了对称我们可以写成:((++a) + ((++a) * (++a)))

请注意,我们可以将其巧妙地表示为一棵树:

   +
  / \
++   *
 |   | \
 a  ++ ++
     |  |
     a  a

这是我们基于优先级和结合性的评估树。

Note that in this case associativity didn't matter at all as all the operators had different precedence. Had our expression been 4 - 1 - 3 + 2, it would've been important to use associativity to reach (((4 - 1) - 3) + 2), as + and - have the same precedence.

现在进入下一步,评估。求值 总是 从左到右发生(即使是赋值,虽然规则有点古怪),但是使用我们刚刚构建的树它是从左到右发生的。

  1. 因此,首先我们开始评估 + 运算符,因为它位于顶部。
  2. 然后我们向左下一层,当我们计算 + 运算符左侧的 ++a 时,(6)
  3. 然后我们往右走,开始评估*操作。
  4. 我们这样做的方法是评估第二个++a(7)
  5. 然后第三个++a(8)
  6. 然后我们将步骤 4 和 5 的结果相乘(这是评估的 * 操作),(56)
  7. 最后我们将第 6 步的结果与第 2 步的结果相加 (62)

...我们完成了。

TL;DR:优先级和结合性决定了放置括号的位置,但求值总是从左到右。

15.7. Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.