假设 i=0 并且数组的所有元素都初始化为 0,则此行的计算顺序是什么 a[i++] = a[i++] + 2;

What's the order of evaluation for this line assuming i=0 and all elements of array are initialized to 0 a[i++] = a[i++] + 2;

提问人:Mustafa Mahmod 提问时间:8/5/2019 最后编辑:Andrew TobilkoMustafa Mahmod 更新时间:8/5/2019 访问量:84

问:

我在 java 中遇到了这行代码,我想知道编译器如何划分这段代码

a[i++] += 2;
a[i++] = a[i++] + 2;
Java 赋值运算符 后增量

评论

0赞 Mustafa Mahmod 8/5/2019
我知道 j=i++;将计算结果为 j=i ;和 i=i+1;那两条线呢
1赞 Turing85 8/5/2019
此外,根据您运行的 java 的确切版本,这个问题(和这个错误)可能很重要

答:

3赞 Andrew Tobilko 8/5/2019 #1

15.26.1. 简单赋值运算符 =

如果左侧操作数是数组访问表达式 (§15.10.3),可能括在一对或多对括号中,则:

首先,计算左操作数数组访问表达式的数组引用子表达式。如果此计算突然完成,则赋值表达式出于同样的原因突然完成;索引子表达式(左手操作数数组访问表达式的)和右手操作数不计算,也不进行赋值。

否则,将计算左操作数数组访问表达式的索引子表达式。如果此计算突然完成,则赋值表达式将出于同样的原因突然完成,并且不会计算右侧操作数,并且不会发生赋值。

https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.26.1

我认为评估的顺序应该如下

a[i++] = a[i++] + 2;
  ^      ^ ^
  1      3 2
         ----------
             ^
             4
------
  ^
  5
--------------------
         ^
         6

我们可以通过运行此代码片段来证明这一点

int[] a = {0, 10, 0, 0};
int i = 0;
a[i++] = a[i++] + 2;

System.out.println(Arrays.toString(a)); // [12, 10, 0, 0]
System.out.println(i);                  // 2

评论

2赞 Andy Turner 8/5/2019
需要指出的一件(也许)有趣的事情是,在任何一个数组取消引用发生之前,都会对这两个 s 进行计算。如果定义 ,则将 “interesting” 行包装在 try/catch 中(以捕获 NPE),在结果 2 之后打印。坦率地说,一个奇怪的结果是,您可以在 LHS 上引用数组分配数组:,LHS 上使用的数组是新分配的数组。i++int[] a = null;ia[i++] = (a = new int[2])[i++];a