从底层分析Java中的i++和++i的区别

从底层分析Java中的i++和++i的区别

在JVM中,每一个Java方法的执行都是一个栈帧入栈出栈( 虚拟机栈)的过程。main方法也是一个栈帧。所有的计算操作(除了自增自减,在局部变量和表中进行)都需要到操作数栈中进行。计算结束之后,再把结果出栈放进局部变量表,或者直接传给下一个方法。即运算是在操作数栈中进行的

i++:执行计算之前先将变量值压栈,然后在局部变量表中由i本身执行+1操作,之后将1压栈,最后将操作数栈中的值赋值给i(所以此时i的值为1)

 * i++ 先赋值在运算,例如 a=i++,先赋值a=i,后运算i=i+1,所以结果是a==1
     	jvm底层理解为:先将i的值压栈,在在局部变量表中执行i+1操作(此时局部变量表中的i为1,但是操作数栈中		的i为0)
 * ++i 先运算在赋值,例如 a=++i,先运算i=i+1,后赋值a=i,所以结果是a==2
        jvm底层理解为:先在局部变量表中执行i+1操作,在将结果1压栈
int i = 0;
i++;
System.out.println(i);

字节码如下:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0				//将常量0压栈
         1: istore_1				//从栈顶取出元素0,赋值给变量
         2: iinc          1, 1		//局部变量+1
         5: getstatic     #2        //sout输出
         8: iload_1					//压栈,将新值1放到栈顶,等待传递给下一个需要使用的方法 
         9: invokevirtual #3        // Method java/io/PrintStream.println:(I)V
        12: return
int j = 0;
j = j++;
System.out.println(j);
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0				//将常量0压栈
         1: istore_1				//从栈顶取出元素0,赋值给变量
         2: iload_1					//将变量0压到栈顶,为计算做准备
         3: iinc          1, 1		//局部变量+1  
         6: istore_1				//计算结果出栈,赋值给i,因为i++先入栈后计算,导致1被0覆盖
         7: getstatic     #2        // sout打印
         10: iload_1				//将变量0压到栈顶,等待传递给下一个需要使用的方法 
         11: invokevirtual #3       // Method java/io/PrintStream.println:(I)V
        14: return

++i

int n = 0++n;
System.out.println(n);
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0				//将常量0压栈
         1: istore_1				//从栈顶取出元素0,赋值给变量
         2: iinc          1, 1		//局部变量+1
         5: getstatic     #2        //sout输出
         8: iload_1					//压栈,将新值放到栈顶,等待传递给下一个需要使用的方法 
         9: invokevirtual #3        // Method java/io/PrintStream.println:(I)V
        12: return

//n = ++n 和 n++ 的结果一样吗? 一样的

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0				//将常量0压栈
         1: istore_1				//从栈顶取出元素0,赋值给变量
         2: iinc          1, 1		//局部变量+1
         5: iload_1					//将1压栈,为计算做准备
         6: istore_1				//计算结果出栈,赋值给n  
         7: getstatic     #2        //sout输出
         10: iload_1				//压栈,将变量值放到栈顶,等待传递给下一个需要使用的方法 
         11: invokevirtual #3        // Method java/io/PrintStream.println:(I)V
        14: return
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值