如何解释这个运算符的关联性?

时间:2015-06-18 09:21:15

标签: java associativity

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

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

并期望表达式为50(作为8 + 7 * 6,增量从右向左开始)。但是表达式由Eclipse从左到右(6 + 7 * 8)进行评估,并将结果表示为62。我是Java中这种关联性的新手,必须缺少明显的东西。请帮助我理解这种奇怪的行为。

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

2 个答案:

答案 0 :(得分:13)

这里有两个不同的东西:表达式解析和表达式评估。

让我们从表达式++a + ++a * ++a开始。我们首先要做些什么?由于运算符+*需要两个操作数,而++需要一个操作数,因此我们必须确定哪个操作符与哪个操作相关。这是表达式解析步骤,其中应用了优先级/关联性。

  1. ++具有最高优先级,因此我们可以将表达式重写为(++a) + (++a) * (++a)
  2. 接下来*,我们再次添加括号:(++a) + ((++a) * (++a))
  3. 最后我们有+,这是所有人的最低优先级,所以为了对称,我们可以写:((++a) + ((++a) * (++a)))
  4. 请注意,我们可以将其整齐地表示为树:

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

    所以这是我们基于优先级和关联性的评估树。

      

    请注意,在这种情况下,关联性并不像所有运营商那样重要   有不同的优先权。如果我们的表达是4 - 1 - 3 + 2,那就是   使用关联性来达到(((4 - 1) - 3) + 2)非常重要,因为+-具有相同的优先级。

    现在进行下一步评估。评估始终从左到右发生(即使是作业,虽然规则有点古怪),但它使用我们刚刚构建的树从左到右发生。

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

      TL; DR :优先级和关联性决定了放置括号的位置,但评估始终是从左到右。

        

      15.7. Evaluation Order

           

      Java编程语言保证运算符的操作数似乎以特定的评估顺序进行评估,即从左到右。

答案 1 :(得分:3)

这是因为乘法运算符*的优先级高于加法+运算符。

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