从i=i++开始的JVM之旅

JVM分类建了很久了,一直都没写,总感觉这方面太头疼,一直都似懂非懂。
今天做到了一道题目  关于i=i++,方法间参数的传递
其实题目也没这么难,也就是i=i++,i的结果的问题。还有方法间参数的传递。
已经写了很久这种东西,基本上没去细细想为什么。反正很自然的做对了。但是看评论还是看到了一个大神通过javap从栈帧的角度去解释了答案,突然发现我能看懂他从JVM的角度去解释答案的过程。
才感觉其实我深入JVM也看了很久了。还是有点体会的。第一次从JVM的角度去思考问题(以前都是似懂非懂,看勉强可以,但是解释是说不清楚道理的,也记不住),有种量变到质变的感觉。所以决定也开始在JVM上写博客了。
加油!

介绍

i++和++i其实到深点就是JVM解释执行引擎的问题。 也就是字节码指令顺序的问题。下面对多个常见操作
i=i++,i++,i=++i,i=i+1来说一下对基于操作数栈的执行引擎

j=j++。

javap:
图示逐行注释:
首先要知道的是栈帧的意思。是虚拟机进行方法调用的和方法执行的数据结构。栈振包含局部变量表,操作数栈和栈帧信息。这里只需要关注局部变量表和操作数栈。(画图能力有限了。。)
一个重要的概念就是Java的是基于栈(操作数栈)的执行引擎。基本上所有的操作都是基于操作数栈。i++和++i自增这类操作比较特殊,是对局部变量表的值进行操作。但是也很好记忆。
好了,开始介绍了。(这里用了2个变量,方便理解局部变量表index)
1   int i=1;   //这个操作的过程(01)就是int值1入栈,然后出栈赋值给局部变量表的i。是栈对1这个元素的入栈出栈操作。。
2  int j =2 //一样(23),栈对2这个元素的入栈出栈操作。
3  j = j++; // 这里看到操作过程(456)先拷贝压栈(副本的j=2),然后局部变量表的j+1;最后局部变量的栈顶值出栈赋值给局部变量表。所以局部变量表的j是等于2的。

j++的情况。

这里应该可以理解到了自增的字节码指令就是iinc,而j=j++多的2步操作是什么呢。就是一个赋值的操作。上面说了是基于栈的操作。所以赋值也要入栈出栈。而在j++中iinc自增优先级是低于iload拷贝入栈的。所以拷贝入栈,自增,然后拷贝的副本出栈赋值。
但是为什么j++打印的结果是3,而j=j++是2呢。
这还是要回到基于栈的操作。要打印j的值,就要把局部变量表的j拷贝入栈,然后打印的方法对栈顶的j进行操作。j++是iinc操作,局部变量表的j+1,而j=j+1操作过后,j其实还是原来的值。
所以结果就不一样啦。

++j

对比上面的j=j++操作可以得知。++j中iinc自增优先级是高于于iload拷贝入栈的。所以自增,拷贝,然后拷贝的副本出栈赋值。

j=j+1;


结合前面的介绍这里应该比较容易理解了。要对j进行操作,就要
4:先拷贝j入栈
5:int常量值1入栈,
6:iadd,最靠近栈顶的2个int型元素相加后结果入栈。
7:栈顶元素出栈,值赋给j。

总结:

总结:从局部变量表和操作数栈的结构,以及基于栈的解释执行引擎的方向去思考的话,应该会对这个自增过程有更深刻的理解。当然方法间参数的传递也可以用栈帧的特性来解释,后面会进行用题目来解释.
参考:<深入Java虚拟机>

转载于:https://www.cnblogs.com/fabaogege/p/10344653.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值