加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

类文件结构

发布时间:2020-12-15 07:21:11 所属栏目:Java 来源:网络整理
导读:1、Java编译器将.java文件编译成为.class文件,实际上,是Java编译器读取源文件内容,经过一些列检查和分析后,整理成标准的、更方便Java虚拟机读取的字节码文件。 2、在官方jdk中默认的Java编译器是javac.exe,虚拟机是java.exe,java.exe实际上包含了真正

1、Java编译器将.java文件编译成为.class文件,实际上,是Java编译器读取源文件内容,经过一些列检查和分析后,整理成标准的、更方便Java虚拟机读取的字节码文件。

2、在官方jdk中默认的Java编译器是javac.exe,虚拟机是java.exe,java.exe实际上包含了真正的虚拟机HotSpot。

3、class文件是Java语言实现平台无关性、机器无关性和语言无关性的基石。

平台无关性:class文件内容屏蔽了关于平台的差异,即不管是windows系统、Linux系统、还是其它支持的系统,class文件都不会因此有差异。

机器无关性:class文件内容屏蔽了关于机器的差异,即不管是intel的x86指令架构或arm指令架构,不管是32位或者64位,class文件都不会因此有差异。

语言无关性:class文件内容屏蔽了关于语言的差异,不管是c语言、python语言等,借助对应的编译器,class文件都可以正常实现和解读。

类文件的结构

目前,我不关心Java编译器是如何将Java源代码编译成字节码文件的,只关心编译后的字节码的内容。

类型 名称 数量
u4 magic 魔数 1
u2 minor_version 次版本号 1
u2 major_version 主版本号 1
u2 constant_pool_count 常量池容量 1
cp_info constan_pool 常量池 constant_pool_count
u2 access_flags 访问标志 1
u2 this_class 本类全限定名 1
u2 super_class 父类限定名 1
u2 interface_account 接口索引容量 1
u2 interfaces 接口索引 interface_account
u2 fields_count 字段表容量 1
field_info fields 字段表 fields_count
u2 methods_count 方法表容量 1
method_info methods 方法表 methods_count
u2 attributes_count 属性表容量 1
attribute_info attributes 属性表 attributes_count

class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符。

class文件中存储的数据类型分为两种:无符号数和表。

无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2字节、4个字节和8个字节的无符号数。

表由表项来组成,表项也可能是另一张表。

魔数

魔数是u4类型,即class文件的前4个字节的内容,作用是确定这个文件是否为一个被虚拟机接受的Class文件。魔数的默认值是0xCAFEBABE。

次版本号和主版本号

此版本号和主版本号都是u2类型,分别为class文件的第5、6个字节和第7、8个字节。

Java的版本号是从45开始的,即主版本号都在45及之上。高版本的JDK能向下兼容以前的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

常量池

紧接着主次版本号之后的是常量池入口,由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。注意,该值是从1开始计数,当值为0x0016,即十进制为22,表示的范围是1~21,共21项常量。

常量池中主要存放两大类常量:字面量和符合引用。

常量池中每一项常量都是一个表,在JDK1.7及之后有14种常量池项目类型,每一种项目都有特定的表结构。

常量 描述 项目 类型 项目描述
CONSTANT_Utf8_info UTF-8编码的字符串 tag u1 值为1
length u2 UTF-8编码的字符串占用的字节数
bytes u1 长度为length的UTF-8编码的字符串
CONSTANT_Integer_info 整型字面量 tag u1 值为3
bytes u4 按照高位在前存储的int值
CONSTANT_Float_info 浮点型字面量 tag u1 值为4
bytes u4 按照高位在前存储的float值
CONSTANT_Long_info 长整型字面量 tag u1 值为5
bytes u8 按照高位在前存储的long值
CONSTANT_Double_info 双精度浮点型字面量 tag u1 值为6
bytes u8 按照高位在前存储的double值
CONSTANT_Class_info 类或接口的符合引用 tag u1 值为7
index u2 指向全限定名常量项的索引
CONSTANT_String_info 字符串类型字面量 tag u1 值为8
index u2 指向字符串字面量的索引
CONSTANT_Fieldref_info 字段的符号引用 tag u1 值为9
index u2 指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
index u2 指向字段描述符CONSTANT_NameAndType的索引项
CONSTANT_Methodref_info 类中方法的符号引用 tag u1 值为10
index u2 指向声明方法的类描述符CONSTANT_Class_info的索引项
index u2 指向名称及类型描述符CONSTANT_NameAndType的索引项
CONSTANT_InterfaceMethodref_info 接口中方法的符号引用 tag u1 值为11
index u2 指向声明方法的接口描述符CONSTANT_Class_info的索引项
index u2 指向名称及类型描述符CONSTANT_NameAndType的索引项
CONSTANT_NameAndType_info 字段或方法的部分符号引用 tag u1 值为12
index u2 指向该字段或方法名称常量项的索引
index u2 指向该字段或方法描述符常量项的索引
CONSTANT_MethodHandle_info 表示方法句柄 tag u1 值为15
reference_kind u1 值必须在1~9范围,它决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为
reference_index u2 值必须是对常量池的有效索引
CONSTANT_MethodType_info 标识方法类型 tag u1 值为16
descriptor_index u2 值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符
CONSTANT_InvokeDynamic_info 表示一个动态方法调用点 tag u1 值为18
bootstrap_method_attr_index u2 值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的的有效索引
name_and_type_index u2 值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读