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

问题描述 投票:4回答:4

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

int x = 3;
x = x++;
// x is still 3

在解释中我们可以读到:

x = x++;线不会离开x == 4,因为++在分配发生后应用。

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

我不同意这个解释。我会用“之前”替换“之后”。

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

  1. x是3。
  2. x++被执行。我将此增量后运算符视为函数: int operator++() { int temp = getX(); setX(temp + 1); return temp; } 所以,在执行x++之后,x是4,但x++表达式返回的值是3
  3. 现在,任务=。只需将返回的3写入x

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

java scjp post-increment
4个回答
11
投票

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

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

你有表达†:

x = ( x++ )

会发生什么(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

iinc发生在istore之前。

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


2
投票

达到官方规范:

  1. postfix ++部分:https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
  2. 赋值运算符部分:https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1

在赋值方面,这是简单的赋值,所以我们遇到了案例3:

  1. 首先,评估左侧操作数以产生变量 - x
  2. 没有错误 - >评估右手操作数 - x++
  3. “将右侧操作数的值转换为左侧变量的类型,进行值集转换(第5.113节)到适当的标准值集(不是扩展指数值集),并且转换的结果存储在变量“

因此,在步骤2中,后缀运算符应该被解析,然后在步骤3中,x再次被赋予其原始值:

call: x = x++;
interframe: LHS is variable 'x'
interframe: RHS caches return value as 3
interframe: x is incremented to 4
interframe: RHS cached value '3' is returned for assignment
interframe: variable x is assigned value 3
call result: x = 3

所以我认为你的书是错的是正确的,并且可能值得联系作者或出版商以发布更正(或添加到勘误页等)


0
投票

x ++表示“使用x然后递增x”。

您也可以使用++ x,这意味着“递增x然后使用x”。

但是,您可以更轻松地做到

x += 1;

-2
投票

++ x称为preincrement,而x ++称为postincrement。

int x = 3;
x = ++x;

例子

int x = 5, y = 5;

System.out.println(++x); // outputs 6
System.out.println(x); // outputs 6

System.out.println(y++); // outputs 5
System.out.println(y); // outputs 6
© www.soinside.com 2019 - 2024. All rights reserved.