Class文件解析
创始人
2025-05-31 18:18:41

目录

Class文件格式总览

常量池(Constant Pool)

数据类型描述规则

成员变量描述规则

成员函数描述规则

字段和方法的数据结构

access_flags

attribute_info

Code属性

LineNumberTable_attribute 

 LocalVariableTable


Class文件格式总览

每一个class文件都对应着唯一一个类或接口的定义信息。

每个class文件都是由字节流组成,每个字节含有8个二进制位,多字节数据项总是按照big-endian(大端模式)的顺序存储。

u4表示4字节

ClassFile {
u4            magic 魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的class文件——魔数值固定(0xCAFEBABE)
u2            minor_version 副版本号
u2            major_version 主版本号
u2            constant_pool_count 常量池计数器   常量池表的索引值只有在大于0小于constant_pool_count才认为有效。
cp_info       constant_pool 常量池  包含class文件结构及其子结构中引用的所有字符串常量,类或接口名和字段名,其它常量。
u2            access_flags 访问标志 由一组标志所构成的掩码,用于表示某个类或接口的访问权限和属性
u2            this_class 类索引,指向类名  必须是对常量池表中某项的一个有效索引值。
u2            super_class 父类索引,指向父类类名 要么是0(超类Object),要么是常量池表中某项的一个有效索引值。
u2            interface_count 接口计数器,表示当前类或接口的直接超接口数量
u2            interfaces[] 接口表 每个成员的值都必须是对常量池表中某项的有效索引值。接口顺序和对应源代码中给定的接口顺序一样。
u2            fields_count 字段计数器,表示当前class文件的fields表的成员个数
field_info    fields[] 字段表 该类和接口所声明的类字段或者实例字段,不包括父类或接口
u2            method_count 方法计数器,表示当前class文件methods表的成员个数
method_info   methods[] 方法表,当前类中方法。不包含超类
u2            attributes_count 属性计数器
attribute_info     attributes[]
}

常量池(Constant Pool)

对应的数据结构伪代码就是一个类型为cp_info的数组。每一个cp_info对象存储了一个常量项。

cp_info {         //u1表示该域对应一个字节长度,u表示unsignedu1 tag;       //每一个cp_info的第一个字节表明该常量项的类型u1 info[];    //常量项的具体内容
}

常量项的类型

 常量项的类型结构

CONSTANT_Utf8_info{u1 tag;u2 length;u1 bytes[length];
}
CONSTANT_String_info{u1 tag;u2 string_index;    //index索引到一个Utf8_info元素 ,利用索引可以减少Class文件占用空间
}
CONSTANT_Class_info{u1 tag;u2 name_index;      
}
CONSTANT_MethodType_info{u1 tag;u2 descriptor_index;    
}
CONSTANT_Fieldref_info{u1 tag;u2 class_index;u2 name_and_type_index;  
} 
CONSTANT_Methodref_info{u1 tag;u2 class_index;u2 name_and_type_index;
}
CONSTANT_InterfaceMethodref_info{u1 tag;u2 class_index;u2 name_and_type_index;
}
CONSTANT_Long_info{u1 tag;u4 high_bytes;u4 low_bytes;
}
CONSTANT_Double_info{u1 tag;u4 high_bytes;u4 low_bytes;
}
CONSTANT_Interger_info{u1 tag;u4 bytes;
}
CONSTANT_Float_info{u1 tag;u4 bytes;
}

数据类型描述规则

1.原始数据类型:"B""C""D""F""I""J""S""Z",分别对应的Java类型为byte、char、double、float、int、long、short、boolean。

2.引用数据类型:"LClassName;",ClassName为对应类的全路径名,比如上"Ljava/lang/String;"

3.数组类型:"[其他类型的描述名",比如一个int数组的描述为"[I",一个字符串数组的描述为"[Ljava/lang/String;",一个二维int数组的描述为"[[I"。

成员变量描述规则

成员变量描述只包含FieldType一种信息,FieldType为数据类型

成员函数描述规则

函数描述包括两个部分,括号内的是参数的数据类型描述,可有0到多个,紧接右括号的是返回值类型描述

如:(Ljava/lang/String;)V。

字段和方法的数据结构

field_info{u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}
Method_info{u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}

access_flags

 

 

attribute_info

属性也分很多类型,由其名称来区别

attribute_info {u2 attribute_name_index;   // 属性名称,指向常量池中Utf8常量项的索引u4 attribute_length;       // 该属性具体内容的长度,即下面info数组的长度u1 info[attribute_length]; // 属性具体内容
}

常见的属性 

Code属性

Code_attribute {u2 attribute_name_index;   //指向内容为"Code"的Utf8_info常量项u4 attribute_length;       //接下来内容的长度u2 max_stack;              //说明这个函数在执行过程中,需要最深多少栈空间u2 max_locals;             //该函数包括最多几个局部变量u4 code_length;u1 code[code_length];      //函数的源码经过编译器转换后得到的Java指令码存储在code数组u2 exception_table_length; //一个try/catch语句对应exception_table数组中的一项 {          u2 start_pc;    //描述try/cath语句从哪条指令开始,指向code数组某处指令u2 end_pc;      //try语句到哪条指令结束u2  handler_pc; //try语句到哪条指令结束u2  catch_type; //catch中截获的Exception或Error的名字,指向Utf8_info常量项。如果catch_type取值为0,则表示它是final{}语句块}        exception_table[exception_table_length];u2 attributes_count;       //还能包含其他属性attribute_info attributes[attributes_count];}

Code_attribute里还能包含的其他常见属性有:

·LineNumberTable用于调试,比如指明哪条指令。对应于源码哪一行。

·LocalVariableTable用于调试,调试时可以用于计算本地变量的值。

·LocalVariableTypeTable,功能和LocalVariableTable类似。

·StackMapTable为Java 1.6以上才支持的属性。JVM加载Class文件的时候,将利用该属性的内容对函数进行类型校验(Type Checking)。

 code数组只能包括Java指令码和操作数

JVM规范中定义的Java指令码的个数不超过255个

Java指令码长度为一个字节。指令码后面跟0或多个参数(占N个字节大小,N>=0)。由规范定义好。

LineNumberTable_attribute 

LineNumberTable_attribute {u2 attribute_name_index;u4 attribute_length;u2 line_number_table_length;{   u2 start_pc;    //指向Code_attribute中code数组某处指令u2 line_number;	//说明start_pc位于源码的哪一行} line_number_table[line_number_table_length];
}

 LocalVariableTable

LocalVariableTable_attribute {u2 attribute_name_index;u4 attribute_length;u2 local_variable_table_length;{   u2 start_pc;   //局部变量在code数组中的有效起始u2 length;     //局部变量在code数组中的有效范围u2 name_index; //此局部变量的名字,指向Utf8_info常量项u2 descriptor_index; //此局部变量的类型,也指向Utf8_info常量项u2 index;} local_variable_table[local_variable_table_length];
}

每个非static函数都会自动创建一个叫作this的本地变量,代表当前是在哪个对象上调用此函数。注意,this对象位于局部变量数组第1个位置(Slot=0)。this作用范围贯穿整个函数,所以从Start=0开始,作用范围为Length=20。

相关内容

热门资讯

杭州重点高中有哪些,杭州有哪些... 杭州重点高中有哪些目录杭州重点高中有哪些杭州有哪些重点高中杭州哪所高中最好杭州重点高中有哪些 ...
女为悦己者容意思,士为知己者死... 女为悦己者容意思目录女为悦己者容意思士为知己者死,女为悦己者容.是什么意思.女人无需为悦己者容悦人不...
北戴河是海吗 极速百科网 极速... 北戴河是海吗目录北戴河是海吗北戴河是海吗 北戴河是海。北戴河古称渝水,清光绪年间,因沙河流经戴...
外婆是什么样的关系,姥姥与我的... 外婆是什么样的关系目录外婆是什么样的关系姥姥与我的关系叫什么关系姥姥是指外婆还是奶奶??我与外婆是什...
头歌--第1关:Linux文件... 任务描述 假设系统中存在一个文件File,修改该文件的权限,根据实际需求...
【Spring从成神到升仙系列... 👏作者简介:大家好,我是爱敲代码的小黄,独...
梦见蜈蚣是什么意思,做梦梦见蜈... 梦见蜈蚣是什么意思目录梦见蜈蚣是什么意思做梦梦见蜈蚣什么意思梦见蜈蚣是什么意思,哪里有解释啊梦见蜈蚣...
小区车位比一般是多少,车库配比... 小区车位比一般是多少目录小区车位比一般是多少车库配比是什么小区总户数8200,总车位是1450个,配...
车锁上的lock什么意思,汽车... 车锁上的lock什么意思目录车锁上的lock什么意思汽车上lock是什么意思?车子上“lock标志”...
kirin710是什么处理器,... kirin710是什么处理器目录kirin710是什么处理器海思kirin710是高通多少?骁龙71...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
跟着文档制作cocos第一个游... 背景 近期打算学习一下cocos creator,想着开发自己的游戏,是...
乌干达是什么梗,网络语乌干达什... 乌干达是什么梗目录乌干达是什么梗网络语乌干达什么意思?乌干达是什么梗乌干达是什么梗乌干达是什么梗 ...
车载电子狗怎么用,怎样使用电子... 车载电子狗怎么用目录车载电子狗怎么用怎样使用电子狗怎么使用电子狗求简答车载电子狗怎么使用车载电子狗怎...
梦见偷东西是什么意思,梦见自己... 梦见偷东西是什么意思目录梦见偷东西是什么意思梦见自己偷东西是什么意思?做梦梦见自己偷东西好不好梦见偷...
黄金瞳到底是什么,黄金瞳电视剧... 黄金瞳到底是什么目录黄金瞳到底是什么黄金瞳电视剧什么时候上映?《黄金瞳》的结局是什么?电视剧《黄金瞳...
前端-session、jwt 目录:   (1)session (2&#x...
企业即时通讯怎样为企业实现移动... 对于企业来说,在办公过程中少不了工作人员相互传递信息和数据传输,企业内部...
骑行选择什么自行车 极速百科网... 骑行选择什么自行车目录骑行选择什么自行车骑行选择什么自行车 1. 山地自行车:适合崎岖不平的路...
蓝色都有哪几种,蓝色都有什么颜... 蓝色都有哪几种目录蓝色都有哪几种蓝色都有什么颜色的蓝图片,蓝色都有什么颜色的蓝二年级蓝色有哪些种类蓝...
如何自学游泳要安全的,初学游泳... 如何自学游泳要安全的目录如何自学游泳要安全的初学游泳的人需要准备哪些东西,注意哪些事项?如何自学游泳...
一年级家长的话怎么写评语,一年... 一年级家长的话怎么写评语目录一年级家长的话怎么写评语一年级学生评价手册家长寄语怎么写一年级最佳家长评...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
docker 镜像管理 查看本地镜像 docker images 可以查看本地下载的镜像 docker images [O...
k8s-1.22.15部署ng... 1.介绍 在前面文章中已经提到,Service对集群之外暴露服务的主要方式有两种&#x...
革命烈士寄语怎么写,清明节缅怀... 革命烈士寄语怎么写目录革命烈士寄语怎么写清明节缅怀先烈的寄语有哪些呢?革命烈士寄语怎么写 革命...
5万元以下新车推荐,5万以下买... 本篇文章极速百科给大家谈谈5万元以下新车推荐,5万以下买什么车好,以及5万以下的新车哪款最好对应的知...
真皮沙发翻新一般多少钱?(真皮... 本篇文章极速百科给大家谈谈真皮沙发翻新一般多少钱?,以及真皮沙发翻新一般多少钱一个对应的知识点,希望...
磨皮什么意思(磨皮是啥?) 磨... 本篇文章极速百科给大家谈谈磨皮什么意思,以及磨皮是啥?对应的知识点,希望对各位有所帮助,不要忘了收藏...
进程间通信【Linux】 1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...