Java执行算术表达式错误?

Java执行算术表达式错误?,java,Java,我不明白Java是如何发展这个算术表达式的 int x = 1; int y = 1; x += y += x += y; System.out.println("x=" + x + " y=" + y); 使用Java,我得到x=4和y=3。但在C、Perl和Php中,我得到x=5和y=3 在纸上,我也得到x=5和y=3,它从右到左开始 1. x += y gives x = 2, y = 1 2. y += ( x +=y ) gives x = 2, y = 3 3. x += ( y

我不明白Java是如何发展这个算术表达式的

int x = 1;
int y = 1;
x += y += x += y;
System.out.println("x=" + x + " y=" + y);
使用Java,我得到x=4和y=3。但在C、Perl和Php中,我得到x=5和y=3
在纸上,我也得到x=5和y=3,它从右到左开始

1. x += y gives x = 2, y = 1
2. y += ( x +=y ) gives x = 2, y = 3
3. x += ( y += x += y ) gives x = 4, y = 3

所以,这一切都是一致的

这显然是令人讨厌的部分:

x += y += x += y;
本协议执行如下:

int originalX = x; // Used later
x = x + y; // Right-most x += y
y = y + x; // Result of "x += y" is the value stored in x
x = originalX + y; // Result of "y += x" is the value stored in y
因此:

重要的部分是在这里使用originalX。复合赋值被视为:

x = x + y
并且+的第一个操作数在第二个操作数之前求值。。。这就是为什么它取x的原始值,而不是最新的值

发件人:

如果左侧操作数表达式不是数组访问表达式,则:

首先,对左侧操作数求值以生成变量。如果此计算突然完成,则赋值表达式也会因为相同的原因突然完成;不计算右侧操作数,也不进行赋值

否则,将保存左侧操作数的值,然后计算右侧操作数的值。如果此计算突然完成,则赋值表达式也会因为相同的原因突然完成,并且不会发生赋值

当有疑问时,请参考语言规范,不要因为两种语言的行为不同就认为其中一种是错误的。只要实际行为与每种语言的特定行为相匹配,一切都是好的——但这确实意味着您需要理解您使用的每种语言的行为


这就是说,您首先应该清楚地避免这种可怕的代码。

不要假设所有语言都以相同的方式处理具有副作用的语句。Java没有弄错,只是定义与其他语言不同。无论如何,你都应该避免这种代码,因为在Java中,这种可怕代码的行为是定义良好的,而至少在C中,它不是。阅读Java语言规范,或者认为它是无用的,因为任何编写这样代码的人都应该被解雇。对我来说这太完美了。我不知道perl、php和C是如何管理的,但对我来说看起来很好。IIRC这实际上是C中未定义的行为,所以它在C中的作用完全没有意义。你的第2步结果是错误的-x是何时/如何回到1的?它应该显示x=2,y=3。如果整个语句都是y+=x+=y,你就会得到这个结果;此时,您需要解释为什么最终值为4。。。这需要更多的工作。但是你还没有解释为什么x+=。。。答案是4,不是5。天真地说,人们可能会认为,如果x的值是2,y的值是3,那么x+=y将给出x=5。重要的一点是,x是在其他任何一个发生之前计算的,这是在最后一步中增加的值,我把它缩短了,你把它延长了。有什么问题吗?在我看来,你根本没有把它放在心上。可以指定一种语言,使复合赋值运算符首先计算右侧,然后计算变量并添加相关的量-您的答案中的所有内容仍然适用,但会给出不同的结果。我简单地回答了问题。当然,如果愿意,您可以深入了解细节,从基本类型和变量定义开始。这只是另一个层次。有人在寻找简短的答案,其他人在寻找较长的答案。如果两者都是正确的,那就好了。
x = x + y