这段时间一直在看JVM相关的书籍,虽然有点难,至少到目前为止尚未放弃。写这篇文章的目的:当作本身这段时间学习的小回顾。本章主要经过几个代码片断,分析下局部变量表与操做数栈之间的数据传递关系,重点讲解iload
,istore
,iconst_<n>
,iadd
命令java
局部变量表:每一个栈帧内部都包含一组称为局部变量表的变量列表学习
操做数栈:每一个栈帧内部都包含一个操做数栈this
iconst_0:把int型的0值压入操做数栈code
iload:将一个局部变量加载到操做数栈上索引
istore:将一个数值从操做数栈上存储到局部变量表中编译
iadd:返回栈顶的两个元素作加法运算,并加结果压栈class
首先经过dos进入TestApp.class所在的目录,而后运行命令javap -c TestApp
,便可看到编译后的字节码文件test
如下是一个java源代码变量
public void test1(){ int c=0; }
编译后的字节码书籍
public void test1(); Code: 0: iconst_0 1: istore_1 2: return
代码分析
由于test1()
是一个实例方法,因此在局部变量表中,索引为0的位置会保存该方法所在类的引用(this),因此才会出现istore_1
而不是istore_0
。
咱们对int c = 0
作下拆解,一个常量0,一个变量c。
0: iconst_0 //将常量0压入操做数栈 1: istore_1 //将栈顶出栈,即c=0 2: return //由于是void,没有返回值
Java源代码以下
public static void test2(){ int c=0; }
编译后的字节码文件
public static void test2(); Code: 0: iconst_0 1: istore_0 2: return
分析
由于test2()
是一个静态的方法,不会在局部变量表中插入任何数据。因此你看到的是istore_0
而不是像程序片断一
中的istore_1
。其余分析跟程序片断一
相同
java源代码
public int test3(){ int c=0; return c; }
编译后的字节码
public int test3(); Code: 0: iconst_0 1: istore_1 2: iload_1 3: ireturn
分析
0: iconst_0 //将常量0压栈 1: istore_1 //将栈顶出栈,及c=0 2: iload_1 //将变量c压入栈顶 3: ireturn //返回栈定元素
Java源代码
public int test4(int a,int b){ int c=0; return a+b; }
编译后的字节码
public int test4(int, int); Code: 0: iconst_0 1: istore_3 2: iload_1 3: iload_2 4: iadd 5: ireturn
** 分析
由于test4(int a,int b)
是实例方法,因此在局部变量表
索引为0的位置会插入this
。
由于test4(int a,int b)
带有两个参数,因此在局部变量索引
索引为1的位置插入a,在索引为2的位置插入b。
0: iconst_0 //将常量0压栈 1: istore_3 //将栈顶出栈,即c=0,将c存储到局部变量表索引为3的位置 2: iload_1 //将局部变量表中索引为1的变量压栈,即a压栈 3: iload_2 //将局部变量表中索引为2的变量压栈,即b压栈 4: iadd //将栈顶两个元素出栈,作加法,而后把结果再入栈(即a,b出栈,将a+b入栈) 5: ireturn //返回a+b的值
java源代码
public int test5(int a,int b){ int c=0; c= a+b; return c; }
编译后的字节码
public int test5(int, int); Code: 0: iconst_0 1: istore_3 2: iload_1 3: iload_2 4: iadd 5: istore_3 6: iload_3 7: ireturn
分析
0: iconst_0 //将常量0压栈 1: istore_3 //将栈顶出栈,及c=0 2: iload_1 //从局部变量表中加载索引为1的变量压栈,即a压栈 3: iload_2 //从局部变量表中加载索引为2的变量压栈,即b压栈 4: iadd //将栈顶两个元素出栈,作加法,而后将结果压栈,及a+b压栈 5: istore_3 //将栈顶元素出栈,并保存到局部变量表中,即c=a+b 6: iload_3 //从局部变量表中加载索引为3的变量压栈,即c压栈 7: ireturn //返回栈顶元素,即返回c