从 JVM 字节码指令来分析i++和++i
1. 前言
当我们遇到像i++
或者--i
这种时可能分不清有啥区别或者说不知道为什么是这样的结果,比如下面
最后结果是4+4*2+3
还是3+5*2+5
还是其他情况呢,++
和*
的优先级谁更高
接下来我们从字节码指令层面去看看到底怎么执行的
2. 栈帧(Stack Frame)
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的虚拟机栈的栈元素
栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。
本文需要了解的是局部变量表和操作数栈
- 局部变量表:局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量,存储在数组中
- 操作数栈:当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈 / 入栈操作。
在活动线程中只有位于栈顶的栈帧的有效的。
3. JVM字节码指令
使用javap -verbose xxx.class
反编译class生成字节码,可以查看常量池、方法、接口、属性等信息
1 |
|
最后就是获取流进行调用实例方法进行输出了,所以最后结果就是2*5 +3+5=18
3.1 图解
4. 避雷
一开始使用的是IDEA的class反编译生成的jvm指令,最后发现结果不太对,找了很久原因才发现是因为IDEA为了方便我们查看class,反编译了class,但是这个class有点不太对,最后导致字节码不太对,使用java自带的命令就没问题,或者使用`jclasslib Bytecode Viewer`这个插件来进行查看
剩下的一个疑问是class既然有问题,最后运行结果为什么没错
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!