当前位置: 首页 > news >正文

Class文件解读

内容导航

  • 摘要
  • 环境
  • 实践
    • 源代码
    • 对应class文件
    • class文件查看
  • class整体结构
  • class解读征途(人工)
    • 1、魔数
    • 2、主版本号
    • 3、副版本号
    • 4、常量池计数
    • 5、常量信息数组
      • 5.1、常量1
        • 5.1.1、常量类型
      • 5.2、常量28
    • 6、访问标志
    • 7、类索引
    • 8、父类索引
    • 9、直接接口计数器
    • 10、接口信息表
    • 11、字段计数器
    • 12、字段信息表
    • 13、方法计数器
    • 14、方法信息表
      • 14.1、方法1
        • 14.1.1、访问标志(access_flags)
        • 14.1.2、方法名索引值(name_index)
        • 14.1.3、描述索引(descriptor_index)
        • 14.1.4、其他属性的数量(attributes_count)
        • 14.1.5、其他属性信息表
          • 14.1.5.1、其它属性信息1
            • 14.1.5.1.1、属性名索引值
            • 14.1.5.1.2、属性长度
            • 14.1.5.1.3、 属性表
      • 14.2、方法2
        • 14.2.1、访问标志(access_flags)
        • 14.2.2、方法名索引值(name_index)
        • 14.2.3、描述索引(descriptor_index)
        • 14.2.4、其他属性的数量(attributes_count)
        • 14.2.5、其他属性信息表
          • 14.2.5.1、其它属性信息1
            • 14.2.5.1.1、属性名索引值
            • 14.2.5.1.2、属性长度
            • 14.2.5.1.3、 操作数堆栈的最大深度
            • 14.2.5.1.4、局部变量的数量
            • 14.2.5.1.5、指令数组长度
            • 14.2.5.1.6、指令信息表
            • 14.2.5.1.6.1、指令信息1
            • 14.2.5.1.7、异常表长度
            • 14.2.5.1.7、异常表
            • 14.2.5.1.8、Code的属性数量
            • 14.2.5.1.9、Code的属性信息
            • 14.2.5.1.9.1、属性1
            • 14.2.5.1.9.1.1、属性名索引
            • 14.2.5.1.9.1.2、属性长度
            • 14.2.5.1.9.1.3、行数表长度
            • 14.2.5.1.9.1.3、行数表
            • 14.2.5.1.9.1.3.1、行数据1
            • 14.2.5.1.9.1.3.2、行数据2
    • 15、属性计数器
    • 16、属性信息表
      • 16.1、属性信息1
        • 16.1.1、属性名索引
        • 16.1.2、属性长度
        • 16.1.3、源文件索引

摘要

您好! 本篇旨在借助Hello World小程序讲解class文件结构,希望给您在您理解class结构的路上推波助澜。如有不足,请不吝赐教。

环境

Java:JDK8
JVM Doc:Java SE 8
class查看器:winhex

实践

源代码

喜闻乐见Hello World,源码如下:

public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } }

对应class文件

javac编译HelloWorld.java生成HelloWorld.class。其过程就不废话

class文件查看

1、用上面列出的工具winhex打开HelloWorld.class,如下:

说明,图片是以1字节为基本单位的十六进制表示的class内容,class实际还是二进制存储的,只不过为了容易查看,将二进制转为十六进制而已。

2、使用如下javap命令查看HelloClass.class结构:

显示内容如下:


此为虚拟机解读出来的结果。我们要做的就是模拟虚拟机解读过程。

class整体结构

参照官方虚拟机规范文档可知,class文件伪结构如下:

ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; }

不一一说明,直接看下图。再有不明白,就看官方虚拟机规范文档.

图片说明:
方格中有文字的都是所占字节长度不确定,无文字的都是占1字节(魔数也在其列,方格中的只是作为固定值展示而已)。

class解读征途(人工)

记住一点,class文件是一串严格有序无分隔符无对齐符二进制流

1、魔数

长度:4字节
值:0xCAFEBABE
对应位置:

说明:固定值,为了表示此文件为一个class文件。

2、主版本号

长度:2字节
值:0x0000
对应位置:

对应javap展示结果:

3、副版本号

长度:2字节
值:0x0034,对应十进制52
对应位置:

说明:与上面次版本号组合标志class文件的版本。如主版本号为M,次版本号为m,则class文件版本为 M.m。
对应javap展示结果:

4、常量池计数

长度:2字节
值:0x001D
对应位置:

说明:十六进制换算成十进制为29,对应数组索引为,0 ~ 28,但索引0位置是虚拟机预留的,不可使用。故索引范围实际为1 ~ 28,表示容量池中仅有28个常量元素。

5、常量信息数组

常量是一个包含多个无符号数和项的复合数据结构。常量的通用伪结构模板如下:

cp_info { u1 tag; u1 info[]; }

因结构中未指定info[]长度,所以不能直接确定一个常量的具体长度。唯一可确定的是常量都是以一个字节的tag常量类型开始,所以只能先确定常量类型,再确定具体的伪结构。

5.1、常量1

5.1.1、常量类型

长度:1字节
值:0x0A
对应位置:

说明:十六进制转为十进制,对应值为10;参照常量类型表

可知,此常量类型为CONSTANT_Methodref,对应的实际伪结构如下:

CONSTANT_Methodref_info { u1 tag; u2 class_index; u2 name_and_type_index; }

所以常量1对应数据位置:

三个红色小框分别对应伪结构的三项:tag、class_index、name_and_type_index。

项目十六进制值十进制值解析值
tag0x0A10CONSTANT_Methodref
class_index0x00066
name_and_type_index0x000F15
对应javap结果:

5.2、常量28

因篇幅问题,省略其它常量的分析过程,直接最后一个常量。

说明:由于常量类型0x01,查常量类型表可知该常量类型为:CONSTANT_Utf8,用来表示常量字符串值。而其对应伪结构如下:

CONSTANT_Utf8_info { u1 tag; u2 length; u1 bytes[length]; }

关于tag上面已经说过;length,占2字节,对应下面字节数组包含的元素数量。u1 bytes[length],表示字节数组,也即,下面是连续length个各占一字节的无符号数,最终应该是个字符串。

项目十六进制值十进制值解析值
tag0x011CONSTANT_Utf8
length0x000615
bytes[length]0x28、0x4C、0x6A、0x61、0x76、0x61、0x2F、0x6C、0x61、0x6E、0x67、0x2F、0x53、0x74、0x72、0x69、0x6E、0x67、0x3B、0x29、0x56(Ljava/lang/String;)V
对应位置:
说明:关于字节数组bytes[]转字符串,可以查询ASCII对照表,可以自己试一试,这里不累赘。

到此,常量池中的内容分析结束,让我们查看一下常量池全内容:

6、访问标志

长度:2字节
值:0x0021
对应位置:

说明:


0x0021转为二进制为:

对照上图可知,分别对应ACC_SUPER、ACC_PUBLIC
对应javap展示结果:

7、类索引

长度:2字节
值:0x0005
对应位置:

说明:此值为常量池索引值,此索引对应的常量的类型必须为CONSTANT_Class
对应javap展示结果:

8、父类索引

长度:2字节
值:0x0006
对应位置:

对应javap展示结果:

说明:此值为常量池索引值,非0索引对应的常量的类型必须为CONSTANT_Class,索引0则表示父类为Object。源码中HelloWorld并没有显式继承父类,这里确出现父类java.lang.Object。正好应证了java.lang.Object是所有类(除去Object)的父类。

9、直接接口计数器

长度:2字节
值:0x0000
对应位置:

说明:十进制数为0,表示没有显式实现接口。官方对此项的说明为:
The value of the interfaces_count item gives the number of direct superinterfaces of this class or interface type.
我理解为:该类或接口类型显式实现或继承的接口数量。

10、接口信息表

因为接口计数器指定值为0,索引接口表为空

11、字段计数器

长度:2字节
值:0x0000
对应位置:

说明:十进制为0,表示没有字段

12、字段信息表

因字段计数器指定值为0,此部分为空

13、方法计数器

长度:2字节
值:0x0002
对应位置:

说明:十进制值为2,有2个方法。

14、方法信息表

方法的伪结构如下:

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

14.1、方法1

14.1.1、访问标志(access_flags)

长度:2字节
值:0x0001
对应位置:

说明:指定十进制值为1,查方法访问标志表

可知,对应ACC_PUBLIC
对应javap展示结果:

14.1.2、方法名索引值(name_index)

长度:2
值:0x0007
对应位置:

说明:对应常量池索引值7所存的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

14.1.3、描述索引(descriptor_index)

长度:2字节
值:0x0008
对应位置:

说明:对应常量池索引值8所存的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

14.1.4、其他属性的数量(attributes_count)

长度:2字节
值:0x0001
对应位置:

说明:此值表示该方法还有一个属性说明

14.1.5、其他属性信息表

其它属性的伪结构如下:

attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info [attribute_length]; }
14.1.5.1、其它属性信息1
14.1.5.1.1、属性名索引值

长度:2字节
值:0x0009
对应位置:

说明:对应常量池索引9对应的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

14.1.5.1.2、属性长度

长度:4字节
值:0x0000001D
对应位置:

14.1.5.1.3、 属性表

根据上面属性长度所指示的值为29,表示接下来29个连续的各占1字节的均为属性信息。
长度:29字节
值:0x00、0x01、0x00、0x01、0x00、0x00、0x00、0x05、0x2A、0xB7、0x00、0x01、0xB1、0x00、0x00、0x00、0x01、0x00、0x0A、0x00、0x00、0x00、0x06、0x00、0x01、0x00、0x00、0x00、0x01
对应位置:

说明:根据属性名code,查询官网文档可知,该code实际伪结构如下:

Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; }

则此部分内容应该对应伪结构中从u2 max_stack开始的所有项。具体我会在对第二个方法解读时候详解。

14.2、方法2

14.2.1、访问标志(access_flags)

长度:2字节
值:0x0009
对应位置:

说明:指定十进制值为9,查方法访问标志表

可知,对应ACC_PUBLIC、ACC_STATIC
对应javap展示结果:

14.2.2、方法名索引值(name_index)

长度:2
值:0x0007
对应位置:
说明:对应常量池索引值11所存的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

14.2.3、描述索引(descriptor_index)

长度:2字节
值:0x0008
对应位置:

说明:对应常量池索引值12所存的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

14.2.4、其他属性的数量(attributes_count)

长度:2字节
值:0x0001
对应位置:

说明:此值表示该方法还有一个属性说明

14.2.5、其他属性信息表

其它属性的通用伪结构如下:

attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info [attribute_length]; }
14.2.5.1、其它属性信息1
14.2.5.1.1、属性名索引值

长度:2字节
值:0x0009
对应位置:

说明:对应常量池索引9对应的常量,该常量类型必须为CONSTANT_Utf8
对应javap展示结果:

则该属性实际伪结构如下:

Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; }

与方法1一致,这里就直接按实际伪结构一一解读。

14.2.5.1.2、属性长度

长度:4字节
值:0x00000025
对应位置:

14.2.5.1.3、 操作数堆栈的最大深度

长度:2字节
值:0x0002
对应位置:

对应javap展示结果:

14.2.5.1.4、局部变量的数量

长度:2字节
值:0x0001
对应位置:

说明:包括用于在调用该方法时将参数传递给该方法的局部变量。对于long或double类型值的最大局部变量索引是 max_locals - 2。任何其他类型的值的最大局部变量索引为max_locals - 1。
对应javap展示结果:

14.2.5.1.5、指令数组长度

长度:4字节
值:0x00000009
对应位置:

14.2.5.1.6、指令信息表

一个字节代表一条指令,可参照官方指令说明

14.2.5.1.6.1、指令信息1

长度:1字节
值:0xB2
对应位置:

查询官方指令对照表可知,表示指令 getstatic

对应javap展示结果:

余下指令查询结果如下:

字节码指令
00nop
02iconst_m1
12ldc
03iconst_0
B6invokevirtual
00nop
04iconst_1
B1return
14.2.5.1.7、异常表长度

长度:2字节
值:0x0000
对应位置:

14.2.5.1.7、异常表

由上面属性可知为空,此项无

14.2.5.1.8、Code的属性数量

长度:2字节
值:0x0001
对应位置:

14.2.5.1.9、Code的属性信息

通用为伪结构如下:

attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; }
14.2.5.1.9.1、属性1
14.2.5.1.9.1.1、属性名索引

长度:2字节
值:0x000A
对应位置:

对应javap展示结果:

查询官网可知,实际对应伪结构为:

LineNumberTable_attribute { u2 attribute_name_index; u4 attribute_length; u2 line_number_table_length; { u2 start_pc; u2 line_number; } line_number_table[line_number_table_length]; }
14.2.5.1.9.1.2、属性长度

长度:4字节
值:0x0000000A
对应位置:

14.2.5.1.9.1.3、行数表长度

长度:2字节
值:0x0002
对应位置:

14.2.5.1.9.1.3、行数表

之前伪结构中已经给出为:

{ u2 start_pc; u2 line_number; }
14.2.5.1.9.1.3.1、行数据1
项目开始位置行号
对应值0x00000x0003
十进制03
对应位置:
对应javap展示结果:
14.2.5.1.9.1.3.2、行数据2
项目开始位置行号
对应值0x00080x0004
十进制84
对应位置:

对应java展示结果位置:

15、属性计数器

长度:2字节
值:0x0001
对应位置:

16、属性信息表

伪结构如下:

attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; }

16.1、属性信息1

16.1.1、属性名索引

长度:2字节
值:0x000D
对应位置:

对应javap展示结果:

则该属性实际的伪结构为:

SourceFile_attribute { u2 attribute_name_index; u4 attribute_length; u2 sourcefile_index; }
16.1.2、属性长度

长度:4字节
值:0x00000002
对应位置:

16.1.3、源文件索引

长度:2字节
值:0x000E
对应位置:

对应javap展示结果:

http://www.jsqmd.com/news/446692/

相关文章:

  • Windows 10 下安装 Docker Desktop
  • 2026年用户口碑最佳的精益管理咨询公司推荐:五家机构服务实效与客户反馈对比 - 品牌推荐
  • 2026年制造企业选型必看:生产现场管理咨询公司适配指南与核心能力拆解 - 品牌推荐
  • 2026年企业增长必看:中国营销管理咨询公司选型指南与精准适配路径 - 品牌推荐
  • 2026年品牌咨询公司深度测评:基于企业增长实效的三维价值解析 - 品牌推荐
  • 2026年制造企业选型必看:精益管理咨询公司适配指南与核心价值点实测 - 品牌推荐
  • 2026年用户口碑最佳全屋定制品牌推荐:五款真实案例与设计服务对比 - 十大品牌推荐
  • 2026年企业选型必看:中国营销管理咨询公司适配指南与核心能力拆解 - 品牌推荐
  • 2026年生产现场管理咨询公司权威榜单:基于实战效果与客户复购率的深度排位赛 - 品牌推荐
  • 2026年中小企业品牌升级必看:五大品牌咨询公司适配指南与选型实测 - 品牌推荐
  • 数字化赋能产业升级:2026年主流企业管理咨询机构竞争力与格局解析 - 十大品牌推荐
  • 2026年用户口碑最佳的精益管理咨询公司推荐:五家机构服务实效与案例对比 - 品牌推荐
  • 2026年企业家口碑推荐:十大企业管理咨询公司服务效果与案例实证 - 十大品牌推荐
  • 宠物眼疾莫慌,福州这些眼科专家服务贴心,宠物眼科/狗狗义眼植入/猫咪眼睑外翻手术/猫咪义眼植入,宠物眼科医生推荐榜单 - 品牌推荐师
  • 2026年用户口碑实证:中国营销管理咨询公司服务效果与客户价值全面对比 - 品牌推荐
  • 2026年木作品牌深度测评:基于材质创新与智能高定的五维竞争力全解析 - 品牌推荐
  • 2026年家装决策必看:全屋定制品牌选型指南与精准适配场景实测 - 十大品牌推荐
  • 2026年北京家居商场选型指南:聚焦局改、适老与全屋智能的场景化适配攻略 - 品牌推荐
  • 2026年上海离婚律所选型指南:基于核心需求与案件复杂度的精准适配分析 - 品牌推荐
  • 2026年品牌咨询公司权威榜单发布:五大机构战略定位与落地能力深度评测 - 品牌推荐
  • 2026年用户口碑实证的上海离婚律所推荐:五家机构真实服务体验与案例对比 - 品牌推荐
  • 【深度解析】激光切管机:技术原理、工业价值与实践应用 - 速递信息
  • 2026年家庭置家必看:北京家居商场选型指南与四大核心价值适配分析 - 品牌推荐
  • 2026年用户口碑实证:上海离婚律所服务满意度与实战案例效果全面对比 - 品牌推荐
  • SwiftOCR与GPUImage:构建iOS端高性能OCR应用的黄金组合
  • 不是洗稿,是学术化重构——百考通降重+降AI,保观点、保逻辑、保原创
  • 2026年高新技术企业认定公司权威榜单发布:五家服务商综合实力深度排位赛 - 品牌推荐
  • PanguFlow,一款简单易用的文件备份软件
  • 面向嵌入式视觉处理的LIFCL-40-7BG400I LIFCL-40-8MG289C LIFCL-40-7MG121I CrossLink-NX™ FPGA系列
  • When a person loses empathy or common sense