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

详解Java的类文件结构(.class文件的结构)

 

  • this_class 指向常量池中索引为 2 的 CONSTANT_Class_info。
  • super_class 指向常量池中索引为 3 的 CONSTANT_Class_info。
  • 由于没有接口,所以 interfaces 的信息为空。

对应 class 文件中的位置如下图所示。

 

06、字段表

一个类中定义的字段会被存储在字段表(fields)中,包括静态的和非静态的。

来看这样一段代码。

public class FieldsTest {private String name;
}

字段只有一个,修饰符为 private,类型为 String,字段名为 name。可以用下面的伪代码来表示 field 的结构。

field_info {u2 access_flag;u2 name_index;u2 description_index;
}
  • access_flag 为字段的访问标记,比如说是不是 public | private | protected,是不是 static,是不是 final 等。
  • name_index 为字段名的索引,指向常量池中的 CONSTANT_Utf8_info, 比如说上例中的值就为 name。
  • description_index 为字段的描述类型索引,也指向常量池中的 CONSTANT_Utf8_info,针对不同的数据类型,会有不同规则的描述信息。

1)对于基本数据类型来说,使用一个字符来表示,比如说 I 对应的是 int,B 对应的是 byte。

2)对于引用数据类型来说,使用 L***; 的方式来表示,L 开头,; 结束,比如字符串类型为 Ljava/lang/String;

3)对于数组来说,会用一个前置的 [ 来表示,比如说字符串数组为 [Ljava/lang/String;

对应到 class 文件中的位置如下图所示。

 

看到这里相信你就能明白经常在 javap 命令中看到的一些奇怪的字符的意思了。

07、方法表

方法表和字段表类似,区别是用来存储方法的信息,包括方法名,方法的参数,方法的签名。

就拿 main 方法来说吧。

public class MethodsTest {public static void main(String[] args) {}
}

先用 jclasslib 看一下大概的信息。

 

  • 访问标记是 public static 的。
  • 方法名为 main。
  • 方法的参数为字符串数组;返回类型为 Void。

对应到 class 文件中的位置如下图所示。

 

08、属性表

属性表是 class 文件中的最后一部分,通常出现在字段和方法中。

来看这样一段代码。

public class AttributeTest {public static final int DEFAULT_SIZE = 128;
}

只有一个常量 DEFAULT_SIZE,它属于字段中的一种,就是加了 final 的静态变量。先通过 jclasslib 看一下它当中一个很重要的属性——ConstantValue,用来表示静态变量的初始值。

 

  • Attribute name index 指向常量池中值为“ConstantValue”的常量。
  • Attribute length 的值为固定的 2,因为索引只占两个字节的大小。
  • Constant value index 指向常量池中具体的常量,如果常量类型为 int,指向的就是 CONSTANT_Integer_info。

我画了一副图,可以完整的表示字段的结构,包含属性表在内。

 

对应到 class 文件中的位置如下图所示。

来看下面这段代码。

public class MethodCode {public static void main(String[] args) {foo();}private static void foo() {}
}

main 方法中调用了 foo 方法。通过 jclasslib 看一下它当中一个很重要的属性——Code, 方法的关键信息都存储在里面。

 

  • Attribute name index 指向常量池中值为“Code”的常量。
  • Attribute length 为属性值的长度大小。
  • bytecode 存储真正的字节码指令。
  • exception table 表示方法内部的异常信息。
  • maximum stack size 表示操作数栈的最大深度,方法执行的任意期间操作数栈深度都不会超过这个值。
  • maximum local variable 表示临时变量表的大小,注意,并不等于方法中所有临时变量的数量之和,当一个作用域结束,内部的临时变量占用的位置就会被替换掉。
  • code length 表示字节码指令的长度。

对应 class 文件中的位置如下图所示。

 

09、QA

评论区有读者问到:“怎么通过索引值,定位到在class 文件中的位置,这个是咋算的?”

在Java类文件中,常量池是一个索引表,它从索引值1开始计数,每个条目都有一个唯一的索引。

  • 常量池计数器:在常量池之前,类文件有一个16位的常量池计数器,表示常量池中有多少项。它的值比实际常量数大1(因为索引从1开始)。
  • 常量池条目:每个常量池条目的开始是一个标签(1个字节),表明了常量的类型(如Class、Fieldref、Methodref等)。根据这个类型,后面跟着的数据结构也不同。

定位过程大致如下:

  • 读取常量池计数器:首先,从类文件的开头读取常量池计数器的值,确定常量池中有多少条目。
  • 遍历常量池:从常量池的第一项开始遍历。由于不同类型的常量长度不同,需要根据每个常量的类型来确定它的长度。
  • 根据索引定位:继续遍历,直到到达所需的索引值。每次遍历时,根据条目类型读取相应长度的数据,直到达到目标索引。

可以抽象成一个数组和一个 for 循环,就能明白了。

int[] constantPool = new int[constantPoolCount];
for (int i = 1; i < constantPoolCount; i++) {int tag = constantPool[i];switch (tag) {case CONSTANT_Integer_info:i += 4;break;case CONSTANT_Float_info:i += 4;break;case CONSTANT_Long_info:i += 8;break;case CONSTANT_Double_info:i += 8;break;case CONSTANT_Utf8_info:int length = constantPool[i + 1];i += length + 1;break;case CONSTANT_String_info:i += 2;break;case CONSTANT_Class_info:i += 2;break;case CONSTANT_Fieldref_info:i += 4;break;case CONSTANT_Methodref_info:i += 4;break;case CONSTANT_InterfaceMethodref_info:i += 4;break;case CONSTANT_NameAndType_info:i += 4;break;case CONSTANT_MethodHandle_info:i += 3;break;case CONSTANT_MethodType_info:i += 2;break;case CONSTANT_InvokeDynamic_info:i += 4;break;default:throw new RuntimeException("Unknown tag: " + tag);}
}

10、小结

到此为止,class 文件的内部算是剖析得差不多了,希望能对大家有所帮助。第一次拿刀,手有点颤,如果哪里有不足的地方,欢迎大家在评论区毫不留情地指出来!

  • class 文件是一串连续的二进制,由 0 和 1 组成,但我们仍然可以借助一些工具来看清楚它的真面目。
  • class 文件的内容通常可以分为下面这几部分,魔数、版本号、常量池、访问标记、类索引、父类索引、接口索引、字段表、方法表、属性表。
  • 常量池包含了类、接口、字段和方法的符号引用,以及字符串字面量和数值常量。
  • 访问标记用于识别类或接口的访问信息,比如说是不是 public | private | protected,是不是 static,是不是 final 等。
  • 类索引、父类索引和接口索引用来确定类的继承关系。
  • 字段表用来存储字段的信息,包括字段名,字段的参数,字段的签名。
  • 方法表用来存储方法的信息,包括方法名,方法的参数,方法的签名。
  • 属性表用来存储属性的信息,包括字段的初始值,方法的字节码指令等。

相信大家看完这篇内容应该能对 class 文件有一个比较清晰的认识了。

相关文章:

详解Java的类文件结构(.class文件的结构)

this_class 指向常量池中索引为 2 的 CONSTANT_Class_info。super_class 指向常量池中索引为 3 的 CONSTANT_Class_info。由于没有接口&#xff0c;所以 interfaces 的信息为空。 对应 class 文件中的位置如下图所示。 06、字段表 一个类中定义的字段会被存储在字段表&#x…...

爆肝整理14天!AI工具宝藏合集

随着AI技术的飞速发展&#xff0c;各类AI工具如雨后春笋般涌现。经过对上百款AI工具的深入探索与测试&#xff0c;我精心挑选出了一些功能强大的AI神器&#xff0c;这些工具将极大地降低自媒体创作的门槛。 &#x1f680;无论是撰写文案、剪辑视频、设计图文&#xff0c;还是处…...

高效库存管理:金蝶云星空与管易云的盘亏单对接方案

高效库存管理&#xff1a;金蝶云星空与管易云的盘亏单对接方案 金蝶云星空与管易云的盘亏单对接方案 在企业日常运营中&#xff0c;库存管理是至关重要的一环。为了实现高效、准确的库存盘点和数据同步&#xff0c;我们采用了轻易云数据集成平台&#xff0c;将金蝶云星空的数据…...

小鹏汽车股价分析:看涨信号已出现,技术指标显示还有40%的上涨空间

猛兽财经核心观点&#xff1a; &#xff08;1&#xff09;小鹏汽车的股价过去几天有所回落。 &#xff08;2&#xff09;随着需求的上升&#xff0c;该公司的业务发展的还算不错。 &#xff08;3&#xff09;猛兽财经对小鹏汽车股价的技术分析&#xff1a;多头已经将目标指向15…...

c语言指针详解2

c语言指针详解2 1.数组名理解 数组名其实是地址&#xff0c;是数组首元素的地址&#xff08;详解1有提及&#xff09; 我们可以根据打印来确认 我们发现数组名和数组⾸元素的地址打印出的结果⼀模⼀样&#xff0c;数组名就是数组⾸元素(第⼀个元素)的地址。 但是上述结论有…...

Chrome DevTools 二: Performance 性能面板

Chrome DevTools 第二篇 Performance 主要介绍performance在我们日常开发中所起到的作用&#xff0c;以及如何利用performance 面板进行性能分析和相关优化建议。 性能面板 Performance 记录和分析页面运行中的所有活动&#xff0c;是解决前端性能问题的重要工具。 1. 控制栏…...

渠道推广如何识别与防止虚假流量?

在当今竞争激烈的游戏市场中&#xff0c;渠道推广作为游戏开发商拓展用户基础、提升市场渗透率的关键手段&#xff0c;其重要性不言而喻。然而&#xff0c;随着市场的发展&#xff0c;渠道作弊问题日益严重&#xff0c;虚假流量、刷假量、拉人风险和违规代充等行为频繁出现&…...

Keil C51 9.61__官网“最新版“下载、安装及相关提示( 保姆级教程, 安装过程详解, 附安装包 )

前言 Keil 5常用的分两个版本&#xff0c;C51 和 MDK。C51用于编译8051内核的单片机程序&#xff0c;譬如AT89C51、STC89C51、STC98C52等。MDK用于编译STM32、GD32等ARM32位内核单片机程序。 ‌Keil C51‌是由Keil Software Company开发的&#xff0c;专门用于8051微控制器的…...

二进制搭建 Kubernetes v1.20

k8s集群master01etcd集群节点1192.168.190.80 kube-apiserver kube-controller-manager kube-scheduler etcdk8s集群node01etcd集群节点2192.168.190.60kubelet kube-proxy docker etcdk8s集群node02etcd集群节点3192.168.190.70etcd VIP192.168.190.100 k8…...

我希望,你把篮球和鸡联系起来想一想。。。

“我希望&#xff0c;你把篮球和鸡联系起来想一想。” “篮球和鸡?” “我有一个好点子…” 目录 创建页面页面准备实现基础样式实现鸡的跑马灯 篮球弹跳实现篮球击出检查是否击中鸡并计算得分实现看一眼就爆炸效果 总结技术点完整代码 创建页面 页面准备 首先开始万恶的第一…...

STM32 ADC介绍

文章目录 STM32 ADC介绍一、ADC的基本概念二、STM32 ADC的主要特点高分辨率&#xff1a;多通道输入&#xff1a;多种工作模式&#xff1a;内置温度传感器和参考电压&#xff1a; 三、ADC的工作原理采样阶段&#xff1a;转换阶段&#xff1a;数据存储&#xff1a; 四、ADC的配置…...

JavaWeb合集12-Redis

十二、Redis 1、Redis 入门 Redis是一个基于内存的key-valule 结构数据库。 特点&#xff1a;基于内存存储&#xff0c;读写性能高 场景&#xff1a;适合存储热点数据(热点商品、资讯、新闻) Redis安装包分为Windows版和Linux版&#xff1a; Windows版 下载地址: https://gith…...

【C++】在Windows中使用Boost库——实现TCP、UDP通信

目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包&#xff0c;然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台&#xff0c;在“bootstrap.…...

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法

怎么提取pdf的某一页&#xff1f;在日常工作与学习中&#xff0c;我们经常会遇到各式各样的PDF文件&#xff0c;它们以其良好的兼容性和稳定性&#xff0c;成为了信息传输和存储的首选格式。然而&#xff0c;在浩瀚的文档海洋中&#xff0c;有时某个PDF文件中的某一页内容尤为重…...

Github优质项目推荐(第八期)

文章目录 Github优质项目推荐 - 第八期一、【manim】&#xff0c;66.5k stars - 创建数学动画的 Python 框架二、【siyuan】&#xff0c;19.5k stars - 个人知识管理软件三、 【GetQzonehistory】&#xff0c;1.3k stars - 获取QQ空间发布的历史说说四、【SecLists】&#xff0…...

快读快写模板

原理 众所周知&#xff0c;在c中&#xff0c;用putchar和getchar输入输出字符的速度是很快的&#xff0c;因此&#xff0c;我们可以考虑把数字转化为字符&#xff0c;按位输出&#xff1b;把字符读入后转化为数字的每一位。 该快读快写可以实现对所有整数类型的输入。 templ…...

make_blobs函数

make_blobs 是 scikit-learn 库中用于生成聚类&#xff08;或分类&#xff09;数据集的函数。它通常用于生成多个高斯分布的簇状数据&#xff0c;以便进行分类或聚类算法的测试和验证。make_blobs 非常灵活&#xff0c;可以控制簇的数量、样本数量、每个簇的标准差、中心点等参…...

特斯拉Optimus:展望智能生活新篇章

近日&#xff0c;特斯拉举办了 "WE ROBOT" 发布会&#xff0c;发布会上描绘的未来社会愿景&#xff0c;让无数人为之向往。在这场吸引全球无数媒体的直播中&#xff0c;特斯拉 Optimus 人形机器人一出场就吸引了所有观众的关注。从多家媒体现场拍摄的视频可以看出来&…...

基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化

目录 前言 一、Java后台程序设计 1、业务层设计 2、控制层设计 二、WebGIS可视化实现 1、侧边栏展示 2、空间边界信息展示 三、标注成果展示 1、面积最大的国家 2、国土面积最小的国家 3、海拔最低的国家 4、最大的群岛国家 四、总结 前言 在前面的博文中&#xff…...

【Linux】/usr/share目录

在Linux和类Unix操作系统中&#xff0c;/usr/share 目录是一个用于存放共享数据文件的目录。这个目录遵循Filesystem Hierarchy Standard (FHS)&#xff0c;它定义了Linux系统中文件和目录的组织结构。/usr 代表 “user”&#xff0c;而 share 表示这些文件可以被系统上的多个用…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...