深入理解i++与++i

为了讲解i++与++i,直接由以下几个例子分析:

例子一

image-20210211153344064

  • 方法test1()和test2()字节码解释:当直接使用i++与++i的时候,反编译字节码文件是一致的,均为

    0 iconst_1 //立即数 1 压入操作数栈
    1 istore_1 //栈顶元素 1 写入到局部变量表索引为1的位置 
    2 iinc 1 by 1 //局部变量表索引为1的数 +1 即 1+1 = 2
    5 return
    

    由此可以得出,执行结果后,局部变量表中的变量 i 为2。

例子二

image-20210211154951865

  • 方法test3()字节码解释:i++赋值给i时,经历了先从局部变量表中数据(i=1)放入到操作数栈中(i=1),然后局部变量表当前变量+1(即i=2),之后将栈顶元素写入到局部变量表中(1覆盖了原来的2),所以最后结果为1!

image-20210211155620204

  • 方法test4()字节码解释:++i赋值给i时,局部变量表当前变量+1(即i=2),然后放入到操作数栈中(i=2),之后将栈顶元素写入到局部变量表中(2–>2),所以最后结果为2!

区别

  • i++是先入栈再加1,栈中元素在写回局部变量表!
  • ++i是先加1再入栈,栈中元素在写回局部变量表!

例子三

image-20210211160527945

  • 方法test5()和test6()字节码解释:如图,注释写的应该比较清晰。

总结

  • 只需记住i++是先入栈再加1,++i是先加1再入栈,在进行计算时,可以画图加深理解。
  • 补充:每个线程都有自己的栈,线程中的每个方法都有自己的栈桢,栈桢中存储着局部变量表,操作数栈,动态链接,方法返回地址以及一些附加信息;栈桢的大小主要是由局部变量表和操作数栈决定。

JMM内存交互操作

image-20210216223833958

内存交互操作有8种,虚拟机实现必须保证每一个操作都是原子的、不可再分的(对于double和long类型的变量来说,load、store、read和write操作在某些平台上允许例外)

  • lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态;
  • unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其它线程锁定;
  • read (读取):作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用;
  • load (载入):作用于工作内存的变量,它把read操作从主存中变量放入工作内存中;
  • use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令;
  • assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中;
  • store (存储):作用于工作内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用;
  • write(写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

原创不易,欢迎转载,转载时请注明出处,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值