Java类文件结构

Class文件

Class文件是一组以8个字节为单位的二进制流。如果遇到需要占用8个字节以上的数据项,按照高位在前的方式分割为多个8个字节进行存储。

类型名称长度
U4megic1
U2minor_version1
U2major_version1
U2constant_pool_count1
cp_infoconstant_poolconstant_pool_count -1
U2access_flags1
U2this_class1
U2super_class1
U2interfaces_count1
U2interfacesinterfaces_count
U2fields_count1
fieldfieldsfields_count
U2methods_count1
method_infomethodsmethods_count
U2attributes_count1
attribute_infoattributesattributes_count

魔数和class文件的版本

megicNum = 0xCAFEBABE
Java版本号从45.0开始。
JDK 13的可生成的最大主版本号为57.0。
高版本JDK向下兼容低版本号Class文件,但是不能运行高版本Class文件。
次版本号作用:

Class文件中使用了该版本JDK尚未列入正式特性清单中的预览功能, 则必须把次
版本号标识为65535, 以便Java虚拟机在加载类文件时能够区分出来。

常量池

常量池的大小constant_pool_count是从1开始计数,其他几个大小的数值都是从0开始。
常量池里面的内容

  1. 字面量
    1. 文本字符串
    2. 声明为final的常量值
  2. 符号引用
    1. 被模块导出或者开放的包
    2. 类和接口的全限定名
    3. 字段的名称和描述符
    4. 方法的名称和描述符
    5. 方法句柄和方法类型
    6. 动态调用点和动态常量

Java代码在Javac编译的时候,不像C或者C++有连接这个步骤,是在虚拟机加载Class文件的时候进行动态连接。

Java中每一项常量都是一个表,截止到JDK13,共有17中常量类型。

访问标志

2个字节标识一些类或者接口层次的访问信息。

标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_FINAL0x0010是否被声明为final,只有类可设置
ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,JDK 1.0.2以后都为真
ACC_INTERFACE0x0200标识这是一个接口
ACC_ABSTRACT0x0400是否为abstract类型,接口和抽象类这个标志为真
ACC_SYNTHETIC0x1000标志这个类并非由用户代码产生
ACC_ANNOTATION0x2000标识这是一个注解
ACC_ENUM0x4000标识这是一个枚举
ACC_MODULE0x8000标识这是一个注解

类索引、父类索引和接口索引集合

这三项数据来确定该类型的继承关系。
需要结合常量池来查找获取数据。数据对应的值是常量池中的index。

字段表集合

fiel_info用于藐视接口或者类中声明的变量。
包括类及变量和实例级变量,但是不包括方法内部声明的局部变量。

字段表结构

类型名称含义数量
u2access_flags访问标志1
u2name_index字段简单名称1
u2descriptor_index字段和方法的描述符1
u2attributes_count属性数量1
attribute_inforattributes属性attributes_count

字段访问标识

标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_PRIVATE0x0002是否为private
ACC_PROTECTED0x0004是否protected
ACC_STATIC0x0008是否为static
ACC_FINAL0x0010是否为final
ACC_VOLATILE0x0040是否是volatile
ACC_TRANSIENT0x0080是否transient
ACC_SYNTHETIC0x1000字段是否由编译期自动产生
ACC_ENUM0x4000字段是否enum

方法表集合

对方法的描述与对字段的描述几乎完全一致。
方法里面的Java代码,经过Javac编译以后,成为字节码指令,存放在方法属性集合中一个名为“Code”的属性里面。

方法表结构

类型名称含义数量
u2access_flags访问标志1
u2name_index字段简单名称1
u2descriptor_index字段和方法的描述符1
u2attributes_count属性数量1
attribute_inforattributes属性attributes_count

方法访问标志

标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_PRIVATE0x0002是否为private
ACC_PROTECTED0x0004是否protected
ACC_STATIC0x0008是否为static
ACC_FINAL0x0010是否为final
ACC_SYNCHRONIZED0x0020是否为sychronized
ACC_BRIDGE0x0040是否是由编译期产生的桥接方法
ACC_VARARGS0x0080是否接受不定参数
ACC_NATIVE0x0100是否为native
ACC_ABSTRACT0x0400是否为abstract
ACC_STRICT0x0800是否为strictfp
ACC_SYNTHETIC0x1000方法是否由编译期自动产生

属性表集合

属性是可以由编译期自定义并解析的。不认识的会被忽略。

预定义的属性

最初只定义了9项,现在Java SE12中已经达到29项。

属性表结构

类型名称含义数量
u2attribute_name_index属性名称索引1
u4attribute_length属性表长度1
u1info自定义的属性值attribute_lenth

code属性

类型名称含义数量
u2attribute_name_index属性名称索引1
u4attribute_length属性表长度1
u2max_stack操作数栈深度的最大值1
u2max_locals局部变量所需的存储空间1
u4code_length字节码长度1
u1code字节码code_lenth
u2exception_table_lenth异常表长度1
exception_infoexception_table异常表exception_table_lenth
u2attributes_count属性长度1
attribute_infoattributes属性attributes_count

其他属性这里就暂不介绍了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值