从字节码层面分析++i和i++的各种情况

情况一

只是单纯的进行i++和++1操作,不赋值。
先说结论:二者没有任何区别

int i = 10;
i++;    // 11

int j = 20;
++j;    // 21

字节码:

 0 bipush 10        //把常量10加载进操作数栈
 2 istore_1         //把操作数栈顶的数值存储到局部变量表
 3 iinc 1 by 1      //把局部变量表1位置的数值进行加1操作(llnc:局部变量自增指令)
 6 bipush 20
 8 istore_2
 9 iinc 2 by 1
12 return

可以看的出来,没有操作数栈的参与,而llnc指令是针对局部变量表的

情况二

进行赋值
结论:二者得到的结果不一样
 

int i = 10;
i = i++;    // 10

int j = 20;
j = ++j;    // 21

字节码指令:

 0 bipush 10        //常量加载进操作数栈
 2 istore_1         //操作数栈顶元素存储进局部变量表中1(即i)的位置
 3 iload_1          //把局部变量表中1位置的数值加载进操作数栈,此时i在表和栈的值都是10
 4 iinc 1 by 1      //把局部变量表中的i进行加1操作,此时i在表中的值是11,在栈中的值是10
 7 istore_1         //把操作数栈顶元素(即i)存储到局部变量表1(即i)的位置并且出栈,此时10覆盖了11
 8 bipush 20        //常量加载进操作数栈
10 istore_2         //操作数栈顶元素存储进局部变量表中2(即j)的位置
11 iinc 2 by 1      //把局部变量表中的j进行加1操作,此时j在表中的值是21,不在栈中
14 iload_2          //把局部变量表中2位置的数值加载进操作数栈,此时j在表和栈的值都是21
15 istore_2         //把操作数栈顶元素(即j)存储到局部变量表2(即j)的位置并且出栈,此时21覆盖了21
16 return

情况三

给其他的变量赋值
        

int i = 10;
int i_1 = i++;    // 10

int j = 20;
int j_1 = ++j;    // 21

字节码指令:

 0 bipush 10    //常量加载进操作数栈
 2 istore_1     //操作数栈存储到局部变量表相应位置(i)
 3 iload_1      //把i加载进操作数栈
 4 iinc 1 by 1  //把局部变量表里的i加1,操作数栈里的i还是10
 7 istore_2     //把操作数栈顶的i(值10)保存到了局部变量表中2的位置(即i_1)
 8 bipush 20    //常量加载进操作数栈
10 istore_3     //操作数栈存储到局部变量表相应位置(j)
11 iinc 3 by 1  //把局部变量表里的j加1
14 iload_3      //把局部变量表里的j加载进操作数栈
15 istore 4     //把操作数栈顶的数值(21)保存到局部变量表中3的位置(即j_1)
17 return

情况四

// 虽然结果一样,但是在字节码指令的顺序不一样
int i = 10;
int j = i++ + ++i;    //22

int x = 10;
int y = ++x + x++;    //22

字节码指令:

 0 bipush 10    //常量加载进操作数栈
 2 istore_1     //操作数栈顶数值保存到局部变量表相应位置(i)
 3 iload_1      //把i加载进操作数栈 操作数栈中的i=10
 4 iinc 1 by 1  //局部变量表中的i加1 此时i=11 操作数栈中的i=10
 7 iinc 1 by 1  //局部变量表中的i加1 此时i=12 操作数栈中的i=10
10 iload_1      //把局部变量表的i加载进操作数栈顶
11 iadd         //把操作数栈顶(12)和次栈顶(10)的数值相加 22,并且把12、10出栈,把22入栈
12 istore_2     //把操作数栈顶数值(22)保存到了局部变量表相应位置(j)
13 bipush 10    //常量加载进操作数栈
15 istore_3     //操作数栈顶数值保存到局部变量表相应位置(x)
16 iinc 3 by 1  //局部变量表中的j加1 此时j=11 (3表示在局部变量表中的位置,1表示加1)
19 iload_3      //把j(11)加载进操作数栈顶位置
20 iload_3      //把j(11)加载进操作数栈顶位置
21 iinc 3 by 1  //局部变量表中的j加1 此时j=12 操作数栈中的j=11
24 iadd         //把操作数栈顶(11)和次栈顶(11)的数值相加 22,并且把11、11出栈,把22入栈
25 istore 4     //把操作数栈顶数值(22)保存到了局部变量表相应位置(y)
27 return

总结

        拿int j = i++ + ++i;来举例
        i(i入栈) -> ++(执行llnc) -> ++(执行llnc) -> i(i入栈) -> +(iadd)
        int y = ++x + x++;也是一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值