为什么赋值的左侧不能是增量表达式?

Sta*_*ust 5 java arrays

有没有人请告诉我Java中以下代码中带有数组的"++"的含义:

   int [ ] arr = new int[ 4 ];
   for(int i = 0; i < arr.length; i++){
        arr[ i ] = i + 1;
       System.out.println(arr[ i ]++);
   }
Run Code Online (Sandbox Code Playgroud)

arr[ i ]++上面的代码是什么意思,为什么我们不能这样做:

arr[ i ]++ = i + 1;
Run Code Online (Sandbox Code Playgroud)

pol*_*nts 7

这里讨论的运算符称为后缀增量运算符(JLS 15.14.2).它被指定为表现如下:

  1. 在运行时,如果操作数表达式的评估突然完成,则后缀增量表达式出于同样的原因突然完成,并且不会发生增量.
  2. 否则,将值1添加到变量的值中,并将总和存储回变量中.
    1. 在添加之前,对值1和变量的值执行二进制数字提升(第5.6.2节).
    2. 如果必要,在存储之前,通过缩小的基元转换(第5.1.3节)和/或经过装箱转换(第5.1.7节)将总和缩小到变量的类型.
  3. 后缀增量表达式的值是所述值的变量的存储在新的值之前.

最后一点是这个问题的关键:你不能做的原因与你不能做arr[i]++ = v;的原因完全相同x++ = v;; 后缀增量表达式返回一个,而不是一个变量.

JLS 15.1评估,表示和结果:

当评估(执行)程序中的表达式时,结果表示以下三种情况之一:

  • 变量[...](在C中,这将被称为左值)
  • 一个值 [...]
  • 没什么(表达被认为是无效的)

赋值需要一个变量在左侧和值不是一个变量,这就是为什么你不能这样做x++ = v;.

来自JLS 15.26分配运营商:

赋值运算符的第一个操作数的结果必须是变量,否则会发生编译时错误.此操作数可以是命名变量[...],也可以是计算变量,可以来自字段[...]或数组访问.[...]

以下代码段显示了错误的分配值的尝试,从相当微妙到更明显:

int v = 42;
int x = 0;
x = v;        // OKAY!
x++ = v;      // illegal!
(x + 0) = v;  // illegal!
(x * 1) = v;  // illegal!
42 = v;       // illegal!
   // Error message: "The left-hand side of an assignment must be a variable"
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用后缀增量运算符的地方在赋值运算符的左侧,只要最后的结果是一个变量.

int[] arr = new int[3];
int i = 0;
arr[i++] = 2;
arr[i++] = 3;
arr[i++] = 5;
System.out.println(Arrays.toString(arr)); // prints "[2, 3, 5]"
Run Code Online (Sandbox Code Playgroud)