b=b++和b++之间的区别是什么?

3
我在面试中被问到以下问题:
int b = 0;
b = b++;
b = b++;
b = b++;
b = b++;

每执行一行后,变量 b 的值是多少? 每行的输出都是 0。 为什么输出不是 0、1、2、3?
4个回答

6
在Java中,表达式
b = b++

等同于

int tmp = b;
b = b + 1;
b = tmp;

因此,这就是结果。
(在其他一些语言中,完全相同的表达式具有未指定的行为。请参见未定义行为和序列点。)

3
提示:
int b = 0, c;
c = b++;
c = b++;
c = b++;
c = b++;
System.out.println(c);

c现在将是3,就像您想的那样,但因为在您的问题中您正在赋值b,它将变为0,因为正如已经解释的那样,它与以下代码相同:

int tmp = b;
b = b + 1;
b = tmp;

3
因为这是b = b++的执行顺序:
  1. b的值存入某个临时变量(可能存入字节码寄存器); 这是b++的第一部分,因为它是一个增量
  2. 将其递增,并将递增后的结果存储在b中(即b++的第二部分)
  3. 将步骤1的值赋给b (即=的结果)

从字节码中我看到 - 2: iload_1 m 3: iinc , 6: istore_1 连续被调用。因此,变量 b 的值首先被加载到堆栈中(从本地变量数组中),然后获取 b 的值,对其进行递增并将其写回变量 b 中。所以,在这里 b 将是 1。然后调用 istore_1,它将从堆栈中弹出 b 的值,并使用堆栈上的当前值(0)覆盖变量 b(本地变量数组)。因此,在 m 特定实现中,字节码级别上的值正在被覆盖 :) - TheLostMind
@TheLostMind:是的,首先在上面的#2中编写,然后在上面的#3中被覆盖。我怀疑如果它是一个热点,HotSpot会...修复它... - T.J. Crowder
这个问题的热点修复会是什么?我只是好奇。它会跳过 iinc 吗? - TheLostMind
@TheLostMind:我对HotSpot的内部机制了解不多,但是HotSpot的工作是加速代码中的hotspots。在这里,我们明显有一个死存储(iinc后面跟着istore_1),所以...谁知道呢,也许它甚至可以将整个东西转化为no-op,因为那就是它的本质。 - T.J. Crowder
也许吧。我有一种感觉,最新的热点可能是这么聪明 :)。谢谢 - TheLostMind

1
"

b++与以下代码相同:

"
int temp = b;
b = b + 1;
return temp;

正如您所看到的,b++ 将返回它的旧值,但会覆盖 b 的值。但是,由于您将返回的(旧)值分配给了 b,新值将被覆盖,因此被“忽略”。

如果您这样写,则会有所区别:

b = ++b; //exactly the same as just "++b"

这首先执行递增操作,然后返回新值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接