参考博客:一看就懂的i++和++i详解
我们知道i++是先自增,然后返回自增之前的值,++i是先自增然后返回自增之后的值
代码如下:
int i = 0;
int a = 0;
a = i++; //i赋值给a,然后自己加一,此时a=0,i=1;
System.out.println(a);
a = ++i; //i自己加一,然后赋给a,此时a=2,i=2;
System.out.println(a);
输出结果:
0 2
class文件如下:
int i = 0;
int a = false;
int i = i + 1;
System.out.println(i);
++i;
System.out.println(i);
下面看i=i++这种情况
int i = 0;
int a = 0;
i = i++;
i = i++;
System.out.println(i);
运行结果:
0
class文件:
int i = 0;
int a = false;
byte var10000 = i;
int var3 = i + 1;
i = var10000;
var10000 = i;
var3 = i + 1;
i = var10000;
System.out.println(i);
我们发现,一开始用var10000把i保存了下来,然后i+1,又用一个新的变量var3保存了下来,然后又把i之前的值赋给了i,这样一来,i又变回去了。
我们把i = i++改成i = ++i试试
int i = 0;
int a = 0;
i = ++i;
System.out.println(i);
输出结果:
1
class文件:
int i = 0;
int a = false;
int i = i + 1;
System.out.println(i);
可以发现,这次i变成了1
原因:
i=i++的字节码指令如下
0: iconst_0 // 生成整数0 1: istore_1 // 将整数0赋值给1号存储单元(即变量i,i=0) 2: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=0,栈顶值为0)
3: iinc 1, 1 // 号存储单元的值+1(此时 i=1)
6: istore_1 // 将数据栈顶的值(0)取出来赋值给1号存储单元(即变量i,此时i=0)
7: getstatic #16 // 下面是打印到控制台指令
10: new #22
13: dup
14: ldc #24
16: invokespecial #26
19: iload_1
20: invokevirtual #29
23: invokevirtual #33
26: invokevirtual #37
29: return
从编码指令可以看出,i
被栈顶值所覆盖,导致最终i
的值仍然是i
的初始值。无论重复多少次i = i++
操作,最终i的值都是其初始值。
简单说就是,i本来是0,执行i++之后,i变成了1,但是返回的是自增之前的数据,所以i又变成了0。