为什么这里不遵循运算符优先级?

Why is the operator precedence not followed here?

在此代码中:

int y = 10;
int z = (++y * (y++ + 5)); 

如我所愿

由于最里面括号的优先级,第一个y++ + 5会被执行。所以 y 的值将是 11,这个表达式的值将是 15。然后 ++y * () 将被执行。所以 12 * 15 = 180。所以 z=180

我得到了什么

z=176

这意味着虚拟机从左到右不遵循运算符优先级。那么我对运算符优先级的理解是错误的吗?

  1. 第一个会被执行++yy 将是 11.
  2. 然后会执行y + 5(其实y++ + 5可以写成5 + y++解释为(5 + y)然后y++)。 z 会变成 11 * 16 = 176.
  3. y计算完成后为12

First y++ + 5 will be executed because of the precedence of the innermost parentheses

优先级和求值顺序不是一回事。除赋值表达式外的所有二元表达式都是从左到右求值的。因此 y++ 在右边括号表达式之前计算。

计算按顺序进行

 z= (++10 * (10++ + 5))
 z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
 z= (11 * 16)
 z= 176 

表达式(++y * (y++ + 5));将被放置在这样的堆栈中:

1. [++y]
2. [operation: *]
3. [y++ + 5] // grouped because of the parenthesis

并且会按顺序执行,结果

1. 10+1 = [11] // y incremented 
2. [operation: *]
3. 11+5 = [16] // y will only increment after this operation

表达式的计算结果为

11 * 16 = 176

括号只是描述子表达式将如何组合在一起。括号并不意味着它将首先被评估。相反,java 中的规则是 严格从左到右评估每个子表达式

永远记住求值顺序与运算符优先级关联性[=34完全无关=].

Java Oracle 文档说:

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.

因此,表达式 (++y * (y++ + 5)) 将被计算为

temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16 
z = temp1*temp2 = 11*16 = 176  

进一步阅读:Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses but equally valid for 也是。