基础知识回顾-虚拟机栈
在java虚拟机中,有内存区域这一块的知识,其中关于虚拟机栈的知识如下:
虚拟机栈表示着java程序方法执行的内存模型,当一个方法执行的时候,则对应的jvm会创建一个栈帧存入虚拟机中,其中栈帧用来存储局部变量表,操作数栈,动态链接,方法出口信息等。当一个方法从执行到执行完毕的时候,则对应,也会有一个栈帧从入栈到出栈的过程。
其中局部变量表用来作为一组变量值的存储空间,即用来存放执行方法的方法入参和方法内定义的局部变量等信息。
操作数栈则是一个栈结构,后入先出,用来执行方法。当方法开始执行的时候,会有各种关于我们编写的程序的字节码指令往整个操作数栈中写入和提取出内容。java的执行引擎被称为“基于栈的执行引擎”,其中的栈就是指的整个操作数栈,因为我们方法内的执行最终靠的还是整个操作数栈来走的。
a++ 底层执行过程
补充了关于操作数栈的知识后,接下来我们就可以进入实操了。
下面编写一个程序,用来简单的执行 a++ 操作;
public class OperationStack {
public static void main(String[] args) {
int a = 99 ;
int b = a++;
System.out.println(b);
}
}
用javac 编译为字节码,然后通过javap 命令,可以查看该程序的字节码执行指令顺序,如下
一条一条的解释,下文中的栈统一指操作数栈
-
bipush 99
指push byte放到栈中,99会被压入栈中
-
istore_1
将栈顶元素弹出,并存在局部变量表当中序号为1 的变量中。
在此处,栈顶元素为99 ,则取出99 并存给局部表中序号为1 的变量,即我们的局部变量a
此处这前两条指令就完成了 a = 99 ; 这条指令。 -
iload_1
从局部变量表中加载指定序号的int存入栈中,此处会拿到序号为1 的int 值 , 即 99,放如操作数栈
-
iinc 1,1
对局部变量表执行++ 操作, 即99+1 = 100,此时局部变量表序号为1 的值为100,但是我们放在操作数栈中的值并没有受到影响
-
issotre_2
即将99 存给局部表中序号为2的变量,即我们的局部变量b,此时 局部变量表中 a = 100 , b == 99;
-
后面的几条指令,则很明显了,就是去加载静态方法,并且取序号为2的变量,并执行pringln方法,最后return
a-- 底层实现原理
public class OperationStack {
public static void main(String[] args) {
int a = 99 ;
int b = ++a;
System.out.println(b);
}
}
这是 ++a 的字节码执行命令顺序,大家可以参考a++ ,读以下,然后感受有什么不同
总结
可以看到, a++ , ++a 在底层实现中,不同的就是iinc的时机, 如果的a++的话 , 那么就会先把值加载到操作数栈中,然后再对局部变量表中a值进行自增,++a 则相反。