x = x ++不会递增,因为在赋值后应用了++?

Ada*_*zyk 4 java scjp post-increment

从OCP Java SE 6程序员实践考试的第280页开始,问题9:

int x = 3;
x = x++;
// x is still 3
Run Code Online (Sandbox Code Playgroud)

在解释中我们可以读到:

x = x++;行不会离开,x == 4因为在分配发生++应用 了该行.

我同意这x是3,我理解增加后.

我不同意这个解释.我会用"之前"替换"之后".

我认为它的工作方式如下:

  1. x 是3.
  2. x++被执行.我将此增量后运算符视为函数:

    int operator++() {
        int temp = getX();
        setX(temp + 1);
        return temp;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    因此,x++执行后,x是4,但从x++表达式返回的值是3.

  3. 现在,分配=.简单地写返回3x.

因此,在我的眼中,在分配发生之前++应用.我错了吗?

Rad*_*def 11

...在分配发生++应用.

好的坚持住.这实际上令人困惑,也许暗示了不正确的行为.

你有表达:

x = ( x++ )
Run Code Online (Sandbox Code Playgroud)

会发生什么(JLS 15.26.1):

  1. x评估赋值左侧的表达式(生成变量).
  2. ( x++ )评估赋值右侧的表达式(生成一个值).
  3. 右侧的评估是:x后递增,表达式的结果是旧的值x.
  4. 左侧的变量x被赋予由右侧的评估产生的值,该值是旧的值x.

所以后增量发生赋值之前.

(因此,正如我们所知,执行语句x x = x++;的值与执行语句x 之前的值相同,即3.)

因此,在我的眼中,在分配发生之前++应用.我错了吗?

你是对的.

从技术上讲,它的指定方式x++是在存储结果之前和赋值运算符的求值过程中进行求值.因此x++可以解释为分配之前期间发生.不是之后,所以这本书看起来都是错误的.

只是为了它,我们也可以看一些字节码:

/*                          int x = 3;                           */
iconst_3 // push the constant 3 on to the stack         : temp = 3
istore_0 // pop the stack and store in local variable 0 : x = temp
/*                          x = x++;                             */
iload_0  // push local variable 0 on to the stack       : temp = x
iinc 0 1 // increment local variable 0 by 1             : x = x + 1
istore_0 // pop the stack and store in local variable 0 : x = temp
Run Code Online (Sandbox Code Playgroud)

iinc之前的情况istore.

†:括号对评估没有影响,它们只是为了清晰起见.