class字节码文件结构

## class字节码文件结构

| 类型 | 名称 | 说明 | 长度 | 数量 |

| ————– | ——————- | ———————- | ——- | ——————— |

| u4 | magic | 魔数,识别Class文件格式 | 4个字节 | 1 |

| u2 | minor_version | 副版本号(小版本) | 2个字节 | 1 |

| u2 | major_version | 主版本号(大版本) | 2个字节 | 1 |

| u2 | constant_pool_count | 常量池计数器 | 2个字节 | 1 |

| cp_info | constant_pool | 常量池表 | n个字节 | constant_pool_count-1 |

| u2 | access_flags | 访问标识 | 2个字节 | 1 |

| u2 | this_class | 类索引 | 2个字节 | 1 |

| u2 | super_class | 父类索引 | 2个字节 | 1 |

| u2 | interfaces_count | 接口计数器 | 2个字节 | 1 |

| u2 | interfaces | 接口索引集合 | 2个字节 | interfaces_count |

| u2 | fields_count | 字段计数器 | 2个字节 | 1 |

| field_info | fields | 字段表 | n个字节 | fields_count |

| u2 | methods_count | 方法计数器 | 2个字节 | 1 |

| method_info | methods | 方法表 | n个字节 | methods_count |

| u2 | attributes_count | 属性计数器 | 2个字节 | 1 |

| attribute_info | attributes | 属性表 | n个字节 | attributes_count |

## Class文件版本号和平台的对应

| 主版本(十进制) | 副版本(十进制) | 编译器版本 |

| —————- | —————- | ———- |

| 45 | 3 | 1.1 |

| 46 | 0 | 1.2 |

| 47 | 0 | 1.3 |

| 48 | 0 | 1.4 |

| 49 | 0 | 1.5 |

| 50 | 0 | 1.6 |

| 51 | 0 | 1.7 |

| 52 | 0 | 1.8 |

| 53 | 0 | 1.9 |

| 54 | 0 | 1.10 |

| 55 | 0 | 1.11 |

## class文件数据类型

| 数据类型 | 定义 | 说明 |

| ——– | ———————————————————— | ———————————————————— |

| 无符号数 | 无符号数可以用来描述数字、索引引用、数量值或按照utf-8编码构成的字符串值。 | 其中无符号数属于基本的数据类型。 以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节 |

| 表 | 表是由多个无符号数或其他表构成的复合数据结构。 | 所有的表都以“_info”结尾。 由于表没有固定长度,所以通常会在其前面加上个数说明。 |

## 类型描述符

| 标志符 | 含义 |

| —— | —————————————————- |

| B | 基本数据类型byte |

| C | 基本数据类型char |

| D | 基本数据类型double |

| F | 基本数据类型float |

| I | 基本数据类型int |

| J | 基本数据类型long |

| S | 基本数据类型short |

| Z | 基本数据类型boolean |

| V | 代表void类型 |

| L | 对象类型,比如:Ljava/lang/Object; |

| [ | 数组类型,代表一维数组。比如:double[][][] is [[[D |

## 常量类型和结构

| 类型 | 标志(或标识) | 描述 |

| ——————————– | ———— | ———————- |

| CONSTANT_utf8_info | 1 | UTF-8编码的字符串 |

| CONSTANT_Integer_info | 3 | 整型字面量 |

| CONSTANT_Float_info | 4 | 浮点型字面量 |

| CONSTANT_Long_info | 5 | 长整型字面量 |

| CONSTANT_Double_info | 6 | 双精度浮点型字面量 |

| CONSTANT_Class_info | 7 | 类或接口的符号引用 |

| CONSTANT_String_info | 8 | 字符串类型字面量 |

| CONSTANT_Fieldref_info | 9 | 字段的符号引用 |

| CONSTANT_Methodref_info | 10 | 类中方法的符号引用 |

| CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符号引用 |

| CONSTANT_NameAndType_info | 12 | 字段或方法的符号引用 |

| CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |

| CONSTANT_MethodType_info | 16 | 标志方法类型 |

| CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |

## 常量类型和结构细节

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

## 访问标志

| 标志名称 | 标志值 | 含义 |

| ————– | —— | ———————————————————— |

| ACC_PUBLIC | 0x0001 | 标志为public类型 |

| ACC_FINAL | 0x0010 | 标志被声明为final,只有类可以设置 |

| ACC_SUPER | 0x0020 | 标志允许使用invokespecial字节码指令的新语义,JDK1.0.2之后编译出来的类的这个标志默认为真。(使用增强的方法调用父类方法) |

| ACC_INTERFACE | 0x0200 | 标志这是一个接口 |

| ACC_ABSTRACT | 0x0400 | 是否为abstract类型,对于接口或者抽象类来说,次标志值为真,其他类型为假 |

| ACC_SYNTHETIC | 0x1000 | 标志此类并非由用户代码产生(即:由编译器产生的类,没有源码对应) |

| ACC_ANNOTATION | 0x2000 | 标志这是一个注解 |

| ACC_ENUM | 0x4000 | 标志这是一个枚举 |

## 字段表访问标志

| 标志名称 | 标志值 | 含义 |

| ————- | —— | ————————– |

| 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_TRANSTENT | 0x0080 | 字段是否为transient |

| ACC_SYNCHETIC | 0x1000 | 字段是否为由编译器自动产生 |

| ACC_ENUM | 0x4000 | 字段是否为enum |

## 类索引、父类索引、接口索引

| 长度 | 含义 |

| —- | —————————- |

| u2 | this_class |

| u2 | super_class |

| u2 | interfaces_count |

| u2 | interfaces[interfaces_count] |

## 属性的通用格式

| 类型 | 名称 | 数量 | 含义 |

| —- | ——————– | —————- | ———- |

| u2 | attribute_name_index | 1 | 属性名索引 |

| u4 | attribute_length | 1 | 属性长度 |

| u1 | info | attribute_length | 属性表 |

## 数据类型和默认初始值对应

| 类型 | 默认初始值 |

| ——— | ———- |

| byte | (byte)0 |

| short | (short)0 |

| int | 0 |

| long | 0L |

| float | 0.0f |

| double | 0.0 |

| char | \u0000 |

| boolean | false |

| reference | null |

本文地址: http://www.yppcat.top/2022/11/20/class字节码文件结构/