最近被同事问道i++和++i的区别,这里总结一下。
先看例子
public static void main(String[] args) {
int a = 0;
for (int i = 0; i < 99; i++) {
a = a ++;
}
System.out.println(a);
int b = 0;
for (int i = 0; i < 99; i++) {
b = ++ b;
}
System.out.println(b);
///////
Integer c = 0;
int d = 0;
for (int i = 0; i < 99; i++) {
c = c ++;
d = d ++;
}
System.out.println(c);
System.out.println(d);
int i = 0;
i = i++ + i++;
System.out.println(i);
int i = 0;
while (i++ <5 ) //先用i的原值与5比较,比较完成后,无论结果是真还是假,都要再进行i=i+1运算
{
System.out.print(i+" ");
}
//这个循环运行5次,输出 1 2 3 4 5,最后的i值是6
int k = 0;
while(++k < 5) //先进行i=i+1运算,然后用i的新值与5比较,判断结果是真还是假
{
System.out.print(k+" ");
}
//这个循环运行4次,输出 1 2 3 4,最后的i值是5
}
执行结果
0
99
0
0
0
1 2 3 4 5
1 2 3 4
i++ 和bai ++i的基本功能是相同的,都是du对变量i进行自增1运算,从zhi功能上讲相当于i =i+1 ;
++运算符分为前缀++和后dao缀++,如i++中的++就是后缀运算符,++i中的就是前缀运算符,两个的区别在于:
前缀++,先使用变量,再进行变量自增1
后缀++,先进行变量自增1,再使用变量
首先该代码在C/C++平台运行 结果是1 因为C/C++所有操作都是在内存中进行的,但是java有虚拟机的概念,虚拟机把内存分块详情见JAVA虚拟机内存详解, 虚拟机运行时 i++ 只改变本地变量表的值 操作栈顶的值还是0 赋值时候 i 从栈顶取出 还是 0
JAVA虚拟机栈描述的是JAVA执行的内存模型
每个帧栈都有局部变量表和操作数栈,在虚拟机眼里如何执行上述代码呢?
0 -> 将int类型的0入栈 放置到操作栈顶部
1 -> 将操作数栈栈顶的值0弹出,保存到局部变量表 index (索引)值为1的位置。(局部变量表也是从0开始的,0位置一般保存当前实例的this引用,当然静态方法例外,因为静态方法是类方法而不是实例方法)
2 -> 将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)
3 -> iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0)
6 -> 将操作数栈顶的值弹出(值0),放到局部变量表index为1的位置(旧值:1,新值:0),覆盖了上一步局部变量表的计算结果。
7 -> 将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)
总结:从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。
参考: