ByteCode篇:i++ 与++i 的简单描述

ByteCode篇:i++ 与++i 的简单描述

首先看一段代码,使用 i 进行自增:

 		int i = 0;
        i++;    //1
        ++i;    //2
        int j = i++;	//3
        int z = ++i;	//4
        int x = ++i + i++;	//5,6
        System.out.println(j);  //j=2
        System.out.println(z);  //z=4
        System.out.println(x);  //x=10
        System.out.println(i);  //i=6

i 一共自增6次,最后结果为6,以上使用数字1-6分别区分每一次的自增。
以下为javap得出的字节码:

		 0: iconst_0
         1: istore_1
         2: iinc          1, 1
         5: iinc          1, 1
         8: iload_1
         9: iinc          1, 1
        12: istore_2
        13: iinc          1, 1
        16: iload_1
        17: istore_3
        18: iinc          1, 1
        21: iload_1
        22: iload_1
        23: iinc          1, 1
        26: iadd
        27: istore        4

首先,调用方法会产生栈帧,栈帧中有操作数栈和局部变量表,为便于理解,贴上局部变量表:

 LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      59     0  args   [Ljava/lang/String;
            2      57     1     i   I
           13      46     2     j   I
           18      41     3     z   I
           29      30     4     x   I

局部变量表中slot为1的即为i存储的位置


 		 0: iconst_0
         1: istore_1

上图操作将常量0写入到局部变量表1中,即初始赋值i=0;

 		2: iinc          1, 1
 		5: iinc          1, 1

上图对应源代码的1和2,可以得出i++ 和 ++i 内部实现都是使用了
iinc slot 1 ,slot代表局部变量表的位置,所以innc实际就是对局部变量表的对应值加1

		 8: iload_1
         9: iinc          1, 1
        12: istore_2
        13: iinc          1, 1
        16: iload_1
        17: istore_3

上图8-12对应3,13-17对应4,即:

  1. i++是先将局部变量表的值加载到操作数栈,再对局部变量表的变量进行自增;
  2. 而++i是先局部变量表自增,再加载到操作数栈。

i++ 就类似使用了一个temp变量存储i自增前的值;

再看最后的x是如何生成的:

		18: iinc          1, 1
        21: iload_1
        22: iload_1
        23: iinc          1, 1
        26: iadd
        27: istore        4

先++i,此时局部变量表中i为5,操作数栈压栈5
后i++,操作数栈又压栈5,局部变量表i再加1为6
之后iadd操作数栈的两个5,将10写入到slot=4,即x的位置
最后x=10,i=6,结果正确

总结

变量自增的操作只是在局部变量表上进行处理,但若出现赋值操作(需要压栈弹栈)就为以下两种处理:

  1. i++是先压栈i,再局部变量表i加1
  2. ++i是先局部变量表i加1,再压栈i(此时i已经增加1)

若只是纯粹对i自增,使用++i和i++就随意了

遗留问题

		int i = 0;
		int y = i++ + i++;
		System.out.println(y); 

请分析y=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值