字节码
- 类元数据
- 接口元数据
- 字段元数据
- 方法元数据
- 属性元数据
主页传送门:📀 传送
类元数据
此部分元数据主要包含类索引(This_Class)和父类索引(Super_Class)。
-
类索引:指向Class字节码常量池表中的一个有效索引值,u2 数据类型,用于确定该类的全限定名。该索引对应的数据项必须为CONSTANT_Class_info类型常量。表示该Class文件定义的类或接口。
-
父类索引:必须为常量池中项目的一个有效索引值,u2数据类型,用于确定该类的全限定名。该索引涉及的数据项同样必须为CONSTANT_Class_info类型常量。若它的值不为0,那么直接表示该Class文件定义的类的直接父类。
-
于接口而言,Class文件的Super_Class项的值必须是常量池中数据项的一个有效索引值。常量池在该索引处的项必须为代表java.lang.Object的CONSTANT_Class_info类型常量。若Class文件的Super_Class的值为0,那么该文件只可能是定义java.lang.Object类,因为它是唯一没有父类的类。
接口元数据
接口元数据主要包含接口计数器(u2的无符号数)和接口数据表(u2的无符号数)俩部分。
接口计数器表示当前类或接口的直接父接口的数量。
接口数据表的每个成员值必须是一个常量池中数据项的有效索引值,它的长度为接口计数器。每个成员interface数据项必须为CONSTANT_Class_info类型常量,其中0<=i<interfaces_count。在interface数据表中。成员表示的接口顺序和对应的源代码中给定的接口顺序(从左至右)一样,即interfaces【0】对应的是源代码中最左边定义的接口。
对比:
类索引 | 父类索引 | 接口索引 |
---|---|---|
u2 | u2 | 一组u2集合 |
确定类的全限定名 | 确定父类的全限定名 | 接口名字索引 |
字段元数据
字段表集合的组成部分与接口相似,也主要包含计数器和数据表、若干索引项,其中字段计数器存储相关的字段的数量;字段数据表记录类或接口中的所有字段,包括实例字段(没有用static修饰)和静态字段(static修饰),但不包括父类或父接口定义的字段与方法中声明的局部变量。
每一个字段表只表示一个成员变量,本类中的所有成员变量构成了字段表集合。字段表结构如下:
类型 | 名称 | 数量 | 说明 |
---|---|---|---|
u2 | access_flags | 1 | 字段的访问标识,与类稍有不同 |
u2 | name_index | 1 | 字段名称索引项 |
u2 | descriptor_index | 1 | 字段描述符索引项,用于描述字段的数据类型。 基本数据类型用大写字母表示; 对象类型用“L 对象类型的全限定名”表示 |
u2 | attributes_count | 1 | 字段表计数器(属性表集合的长度) |
attribute_info | attributes | attributes_count | 字段表(属性表集合,用于存放属性的额外信息,如属性的值。) |
字段访问权限值如下:
标志值 | 值 | 说明 |
---|---|---|
ACC_PUBLIC | 0x0001 | public,包外可访问 |
ACC_PRIVATE | 0x0002 | private,只可在类内访问 |
ACC_PROTECTED | 0x0004 | protected,类内和子类中可访问 |
ACC_STATIC | 0x0008 | static,静态 |
ACC_FINAL | 0x0010 | final,常量 |
ACC_VOLATILE | 0x0040 | volatile,直接读写内存,不可被缓存,不可和ACC_FINAL 一起使用 |
ACC_TRANSIENT | 0x0080 | tramsient,在序列化中被忽略的字段 |
ACC_SYNTHETIC | 0x1000 | synthetic,由编译器产生,不存在于源代码中 |
ACC_ENUM | 0x4000 | enum,枚举类型字段 |
注意:接口中的字段必须同时设置ACC_PUBLIC 、ACC_STATIC、ACC_FINAL。
方法元数据
方法表结构与字段表类似。
volatile 关键字 和 transient 关键字不能修饰方法,所以方法表的访问标志中没有 ACC_VOLATILE 和 ACC_TRANSIENT 标志。
方法表的属性表集合中有一张 Code 属性表,用于存储当前方法经编译器编译后的字节码指令。
属性元数据
在字段表、方法表中可以携带自己的属性表集合,用来描述某些场景专有信息。属性表的格式相对固定,包含三部分:一个u2的attribute_name_index,指向常量池中的一个UTF-8字符串常量,表示一个属性名称;一个u2的数据类型表示attribute_length,表示该属性值的字节长度,结构表如下:
类型 | 名称 | 数量 | 含义 |
---|---|---|---|
u2 | attribute_length | 1 | 属性长度 |
u2 | attribute_name_index | 1 | 属性方法下标 |
attribute_info | attributes | attribute_count | 属性信息表 |
属性信息表如下:
属性名称 | 使用位置 | 说明 |
---|---|---|
Code | 方法表 | 被编译成字节码的指令 |
ConstantValue | 字段表 | final关键字定义的常量值 |
Deprecated | 类、方法表、字段表 | 声明deprecated的方法和字段 |
Exceptions | 方法表 | 方法抛出异常 |
InnerClasses | 类文件 | 内部类列表 |
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论 你的支持就是我✍️创作的动力! 💞💞💞