怎么是x = 20; x = ++ x + ++ x + x ++; java中x的最终值是65

这怎么可能,因为后增量运算符应该将x增加到66?

当我为y = ++ x + ++ x + x ++做同样的事情时; 它为y给出了值65,为x给出了23。

那么让我知道java编译器如何解决这些表达式。

让Java告诉你。 javap -c MyClass显示字节码:

  public static void main(java.lang.String[]); Code: 0: bipush 20 2: istore_1 3: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 6: iinc 1, 1 9: iload_1 10: iinc 1, 1 13: iload_1 14: iadd 15: iload_1 16: iinc 1, 1 19: iadd 20: dup 21: istore_1 22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 25: return 

如果你想一想,结果是完全合乎逻辑的:你有两个前增量和一个后增量。 所以,你的代码生效了:

 y = 0 x++ // 21 y += x x++ // 22 y += x y += x // (still 22!) x++ // 23 x = y // (21 + 22 + 22 at this point) 

++ x与x ++不同

++ x在同一行中完成任何操作之前递增x。

x ++在同一行中完成任何操作后递增x。

要计算到65,它必须进行如下计算。

(1 + 20)+(1 + 21)+(22)= 65

之后,x将是23

我认为y =(++ 20)+(++ 21)+ 22 = 21 + 22 +22 = 65

那么让我知道java编译器如何解决这些表达式。

Java编译器只是实现了Java语言规范。

如果你真的需要理解编译器如何评估这样的可怕和奇怪的语句,你需要理解规范的相关部分:

  • 15.7评估订单
  • 15.14.2后缀增量运算符++
  • 15.15.1前缀增量运算符++

等等。

首先,你应该明白这一点:

++i递增i并返回i

i++返回i然后递增它。

现在我们已经建立了这个,让我们打破程序。

在程序开始时, x = 20 。 所以, ++x会返回21.现在当你再次以这种方式递增x时,你将增加21而不是20 。 因此, ++x + ++x将评估为21 + 22 ,等于43.在程序的这一点上, x等于22 。 因此,如果将x++添加到43,则将x的值添加到43,然后再增加x 。 这最终导致y具有值65,并且x具有值23。

不要对同一个表达式中的同一个变量使用++和=,增量不会生效。 来自Java™Puzzlers:陷阱,陷阱和角落案例作者:Joshua Bloch,Neal Gafter Puzzle#25:

正如拼图的标题所暗示的那样,问题在于增量的声明:

j = j ++;

据推测,该语句的作者意味着它将j的值加1,这就是j ++的表达式。 不幸的是,作者无意中将这个表达式的值赋给了j。 当置于变量之后时,++运算符用作后缀增量运算符[JLS 15.14.2]:表达式j ++的值是j之前的原始值。 因此,前面的赋值首先保存j的值,然后将j设置为其值加1,最后将j重置为其原始值。 换句话说,赋值等同于这个语句序列:

int tmp = j;

j = j + 1;

j = tmp;

因此,在评估时,您的母鹿看起来像这样:

 int x=20 int sum; x=x+1; //x=20=1 sum=x; //sum and x equal 21 x=x+1; //x=22 sum=sum+x; //sum=43 sum= sum+x; //sum=65 x= x+1; //x=23 x=sum; //x=65; 

这就是为什么x = 65而​​不是66

总体而言,这是糟糕的编程,永远不应该在实际代码中使用,因为它很容易在所有前后增量中丢失。

但这是基本的解释。

 simple enough: x = 20 Here is where it gets messy: y = ++(20) + ++(++(20)) + (++(++(20)))++ Pre increment --> ++x Post increment --> x++ Pre increments happen inside the evaluation and post increments happen after the evaluation. So that statement can be reduced in the following steps. y = 21 + ++(21) + (++(21))++ y = 21 + 22 + (22)++ y = 21 + 22 + 22 y = 65 After all these increments x = 23. In the statement above though, x equals multiple numbers because of all the pre and post increments. 

故事的道德,不要这样做,并且在评估表达式之前进行预增量,并且在评估表达式之后发生增量。

你应该记住这个C运算符优先级

所以后增量先行++X = 20然后x++=22然后x++ = 23总共65。