- 查看字节码工具:Idea插件(jclasslib)
- 一堆十六进制数,JVM以两个十六进制值为一组,一个十六进制数表示4位(0000),8位等于一个字节,即以字节为单位进行读取
- 字节码文件由十部分按固定顺序组成
魔数 版本号 常量池 访问标志 当前类在常量池中的索引 父类在常量池中的索引 接口在常量池中的索引 字段表 方法表 附加属性
-
魔数:0xCAFEBABE
-
版本号:次版本号+主版本号 各2个字节
-
常量池:常量池计数器+常量池数据区
-
计数器:用两个字节来表示常量池大小 复制代码
-
数据区: 1. 字面量(final修饰的常量值和八种基本数据类型:byte、short、int、long、float、double、boolean、char)。 注:当 int 取值 -1~5 采用 iconst 指令,以及 取值 -128~127 采用 bipush 指令-----不会放入常量池, 取值 -32768~32767 采用 sipush 指令,取值 -2147483648~2147483647 采用 ldc 指令。-----会放入常量池 2. 符号引用-(类和接口的全限定名,方法和字段的名称和描述符-类型) 复制代码
-
-
访问标志:两个字节,描述该Class是类还是接口,以及被哪些修饰符修饰。
例如Public=0x0001,多个修饰符则或(ACC_PUBLIC | ACC_FINAL,即0x0001 | 0x0010=0x0011) -
当前类名:当前类的全限定名。
两个字节,为常量池中的索引值,根据索引值可以在常量池中找到这个类的全限定名。 -
父类名称:父类的全限定名,同上。
-
接口信息:
接口计数器,两个字节,描述了该类或父类实现的接口数量。紧接着的n个字节是所有接口名称的字符串常量的索引值。 -
字段表:字段表计数器+权限修饰符(private)+字段名索引+字段描述符索引+属性个数+属性列表
-
方法表:方法计数器+权限修饰符+方法名索引+描述符索引+属性个数+属性列表
构造方法也是一个init方法。 方法的属性可以分为code区(存放着16进制操作码)+行号表+本地变量表,code区其实就是所说的字节码指令, 十六进制值操作码与助记符的对应关系和用处可以查看Oracle官方文档了解 JVM的指令集是基于栈而不是寄存器,基于栈可以具备很好的跨平台性(因为寄存器指令集往往和硬件挂钩) 但是栈只是一个FILO结构,需要频繁的压栈出栈,并且栈是在内存中实现, 而寄存器是在CPU的高速缓冲区,相较而言基于栈的速度要慢很多。 复制代码
- 附加属性表:该文件中类或接口所定义属性的基本信息。
参考资料:
字节码增强技术探索:tech.meituan.com/2019/09/05/…
Java常量池:blog.csdn.net/Viscu/artic…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END