字节码
由8位组成,最多支持256个操作码。目前已有约200个
主要包含四类
- 栈操作指令(如局部变量交互)—> iconst、aload
- 流程控制指令(如if while)
- 对象操作指令(如调用方法)
- 算术运算指令(如add divide)—> iadd
编译字节码
javac编译工具
javac com/xxx/yyy/A.java 生成 A.Class文件
字节码助记符
javap 反汇编工具,其中-c进行反汇编,-verbose显示详细信息
查看字节码:javap -c com.xxx.yyy.A
汇编内容中通常包含
常量池、堆中对象引用、方法中的局部变量表以及操作数栈,示例如下
Warning: Binary file TestDate contains com.justest.test.TestDateCompiled from "TestDate.java"public class com.justest.test.TestDate {//默认的构造方法,在构造方法执行时主要完成一些初始化操作,包括一些成员变量的初始化赋值等操作public com.justest.test.TestDate();// 以下为操作数栈的操作过程Code:0: aload_0 //从本地变量表中加载索引为0的变量的值,也即this的引用,压入栈1: invokespecial #10 //出栈,调用java/lang/Object."<init>":()V 初始化对象,就是this指定的对象的init()方法完成初始化4: aload_0 // 4到6表示,调用this.count = 0,也即为count复制为0。这里this引用入栈5: iconst_0 //将常量0,压入到操作数栈6: putfield //出栈前面压入的两个值(this引用,常量值0), 将0取出,并赋值给count9: return//指令与代码行数的偏移对应关系,每一行第一个数字对应代码行数,第二个数字对应前面code中指令前面的数字LineNumberTable:line 5: 0line 7: 4line 5: 9//局部变量表,start+length表示这个变量在字节码中的生命周期起始和结束的偏移位置(this生命周期从头0到结尾10),slot就是这个变量在局部变量表中的槽位(槽位可复用),name就是变量名称,Signatur局部变量类型描述LocalVariableTable:Start Length Slot Name Signature0 10 0 this Lcom/justest/test/TestDate;public static void main(java.lang.String[]);Code:// new指令,创建一个class com/justest/test/TestDate对象,new指令并不能完全创建一个对象,对象只有在初,只有在调用初始化方法完成后(也就是调用了invokespecial指令之后),对象才创建成功,0: new //创建对象,并将对象引用压入栈3: dup //将操作数栈定的数据复制一份,并压入栈,此时栈中有两个引用值4: invokespecial #20 //pop出栈引用值,调用其构造函数,完成对象的初始化7: astore_1 //pop出栈引用值,将其(引用)赋值给局部变量表中的变量testDate8: aload_1 //将testDate的引用值压入栈,因为testDate.test1();调用了testDate,这里使用aload_1从局部变量表中获得对应的变量testDate的值并压入操作数栈9: invokevirtual #21 // Method test1:()V 引用出栈,调用testDate的test1()方法12: return //整个main方法结束返回LineNumberTable:line 10: 0line 11: 8line 12: 12//局部变量表,testDate只有在创建完成并赋值后,才开始声明周期LocalVariableTable:Start Length Slot Name Signature0 13 0 args [Ljava/lang/String;8 5 1 testDate Lcom/justest/test/TestDate;
https://blog.csdn.net/luanlouis/article/details/39960815
其他内容需要结合JVM模型的栈进行解释
