在Java中,为什么在计算表达式的其余部分之前,括号中的赋值不会出现?

时间:2014-07-27 17:32:15

标签: java operator-precedence

考虑

int a = 20;
a = a + (a = 5); // a == 25, why not 10?

括号不要胜过所有优先规则吗?在评估某些表达式之前,RHS上的一些变量是否已预先填充?

3 个答案:

答案 0 :(得分:5)

因为在您拥有的示例中首先加载a,然后然后评估括号中的位。如果您颠倒了订单:

int a = 20;
a = (a = 5) + a;
System.out.println(a);
10

...你确实得到10.表达式从左到右进行评估。

考虑一下:

f() + g()

f将在g之前调用。想象一下,在

中会有多么不直观
f() + (g())

要在g之前调用f

JLS §15.7.1详细介绍了这一点(感谢@paisanco在评论中提出这一点。)

答案 1 :(得分:4)

来自JLS

  

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

  

二元运算符的左侧操作数似乎是完全的   在评估右手操作数的任何部分之前进行评估。

在括号中包装表达式只是为了帮助分组(和关联性),它不会强迫它的评估发生在它左边的任何东西之前。

答案 2 :(得分:2)

生成的字节码:

BIPUSH 20
ISTORE 1
ILOAD 1
ICONST_5
DUP
ISTORE 1
IADD
ISTORE 1
RETURN
LOCALVARIABLE a I

首先,为第一个变量(a)指定20:

BIPUSH 20
ISTORE 1

然后,将第一个变量的内容加载到堆栈中(20放在堆栈上):

ILOAD 1

然后,你推动常数' 5'到堆栈两次(20 5 5):

ICONST_5
DUP

然后,将堆栈顶部存储到第一个变量(a):

ISTORE 1

a现在是5,堆栈现在是(20 5)。我们添加两个操作数并将它们的和加到第一个变量(a):

IADD
ISTORE 1

因此,a现在是20 + 5 = 25.我们结束:

RETURN