Class字节码文件
Class字节码文件
概述
Java源代码的编译结果是字节码,那么肯定需要有一种编译器能够将Java源码编译为字节码,承担这个重要责任的就是配置在path环境变量中的javac编译器。javac是一种能够将Java源码编译为字节码的前端编译器。
源代码经过编译器编译之后便会生成一个字节码文件,字节码是一种二进制的类文件,它的内容是JVN的指令,而不像C、C+t经由编译器直接生成机器码。
Java的跨平台性:
Java虚拟机不和包括 Java 在内的任何语言绑定,它只与“Class 文件”这种特定的二进制文件格式所关联。无论使用何种语言进行软件开发,只要能将源文件编译为正确的Class文件,那么这种语言就可以在Java虚拟机上执行。
class字节码文件可以通过JDK自带的javap命令来反编译查看
字节码文件结构
Class文件的总体结构如下:
魔数
类型:u4(4个字节的无符号整数)
名称:magic
说明:用于识别Class文件格式
Class文件版本
类型:u2+u2(4个字节的无符号整数)
名称:minor_version+major_version
说明:包含一个副版本号(minor_version),在第5,6字节;一个主版本号(major_version),在7,8字节
常量池
常量池是class文件中内容最为丰富的区域之一。常量池对于Class文件中的字段和方法解析也有着至关重要的作用。
常量池计数器:
类型:u2
名称:constant_pool_count
说明:由于常量池的数量不固定,时长时短,所以需要放置两个字节来表示常量池容量计数值。(0项被空出来了)
常量池表:
类型:cp_info
java1
2
3
4
5
6cp_info{
// 标识是什么类型的表项
u1 tag;
// 具体内容
u1 info[];
}名称:constant_pool
说明:常量池的映射表,用于存放编译时期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放
虚拟机在加载cClass文件时才会进行动态链接,也就是说,Class文件中不会保存各个方法和字段的最终内存布局信息,因此,这些字段和方法的符号引用不经过转换是无法直接被虚拟机使用的。当虚拟机运行时,需要从常量池中获得对应的符号引用,再在类加载过程中的解析阶段将其替换为直接引用,并翻译到具体的内存地址中。
访问标志
类索引,父类索引,接口索引集合
类索引:
类型:u2
名称:this_ckass
说明:类索引用于确定这个类的全限定名
父类索引:
类型:u2
名称:super_class
说明:父类索引用于确定这个类的父类的全限定名。由于Java语言不允许多重继承,所以父类索引只有一个,除了java.lang.0bject之外,所有的Java类都有父类,因此除了java.lang.Object 外,所有Java类的父类索引都不为0。
接口索引:
类型:u2+u2*interfaces_count
名称:interfaces_count+interfaces[interfaces_count]
说明:接口索引集合就用来描述这个类实现了哪些接口,这些被实现的接口将按 implements 语句(如果这个类本身是一个接口,则应当是extends 语句)接口顺序从左到右排列在接口索引集合中。
字段表集合
字段表计数器:
- 类型:u2
- 名称:fields_count
- 说明:fields_count的值表示当前class文件fields表的成员个数。
字段表集合:
方法表集合
方法表计数器:
- 类型:u2
- 名称:methods_count
- 说明:methods_count的值表示当前class文件methods表的成员个数。
方法表集合:
属性表集合
属性表计数器:
- 类型:u2
- 名称:attributes_count
- 说明:attributes_count的值表示当前class文件属性表的成员个数。
属性表集合:
v1.5.2