JVM的故事——类文件结构
类文件结构
文章目录
- 类文件结构
- 一、概述
- 二、无关性基石
- 三、Class类文件的结构
一、概述
计算机是只认由0、1组成的二进制码的,不过随着发展,我们编写的程序可以被编译成与指令集无关、平台中立的一种格式。
二、无关性基石
对于不同平台和不同平台的Java虚拟机,都支持一种程序存储格式—字节码。Java虚拟机并不与Java这个语言绑定,它只与class文件绑定。任何语言编译后生成的class文件都可以在Java虚拟机上运行。

三、Class类文件的结构
Java语言一直保持着良好的向后兼容性,Class文件结构的稳定功不可没。在Java语言经历了许多的改进和更新,Class文件的结构和功能几乎没有变化,只有一些新增和补充内容。
任何一个class文件都对应着唯一的一个类或者接口的定义信息,但并不一定每个类或者接口都有着对应的class文件(可以动态生成,直接进入类加载器中)。
Class文件是一组以8个字节为基础单位的二进制流,中间没有任何的分隔符。当遇到大于8个字节的空间存储时,会按照高位在前把变量分割成若干个8个字节进行存储。Class文件存储数据只通过两种结构:无符号数和表。u1、u2、u8代表1、2、8个字节的无符号数。表是由多个无符号数或者其它表构成的结构,表的命名都习惯性地以”_info”结尾。整个class文件也可以看成一张表,表的组成结构如下图。

1、魔数与Class文件的版本
每个class文件的头四个字节是魔数,这是用来辨别该class文件是否可以被虚拟机接受。许多类型的文件都有魔数,例如gif、jpg等。使用魔数比使用后缀名辨别文件格式更加安全,因为后缀名是可以更改的。文件格式的魔数由制定者自己定义,class文件的魔数是0XCAFEBABE
紧接着魔数后面的四个字节是class文件的版本号定义,第五六字节定义的是次版本号(minor version),第七八字节定义的是主版本号(major version)。Java的class文件版本号是从45开始的,每个Java的大版本发布,主版本号就加一。高版本JDK可以兼容低版本的class文件。

分析此图,由5、6位是0x0000可以得出次版本号为0,由7、8位是0x0032可以得出主版本号是50,所以该class文件版本号是50.0,对应的JDK版本应该是JDK1.6,JDK1.6能支持版本号为45.0-50.65535的class文件。
2、常量池
在主次版本号之后的就是常量池,它是class文件中的资源仓库,占用着大量的数据,也是第一个出现的表类型数据项。
常量池的入口需要放置一个u2类型的数据,来表示有多少常量。这个容量的计数是从1开始而不是从0开始的

如此图,可以看见偏移地址0x00000008处,值为0x0016,即常量池的容量为22,那么就有21个常量,索引为1-21。把0空出来是为了表达不引用任何一个常量来设计的。不过除了常量池的其它集合,索引还都是从0开始的。
常量池中的每一个常量都是一个表,截止JDK13,常量表中一共有17种不同类型的常量。这些常量表都有一个相同的特点,就是它们的第一位是u1类型的标志位。

下面开始对常量进行分析

第0x00000008偏移位说明了有21个常量。从0x0000000A开始,0x07是第一个常量的标志位(tag),根据6-3常量池的项目类型可以得知这是一个类或接口的符号引用

根据表6-4就可以知道接下来两个字节要表示这个常量的name_index,即常量池的索引值。它指向一个CONSTANT_Utf8_info类型常量,这个常量代表类的全限定名。从偏移位0x0000000B开始,可以知道该常量的索引值为0x0002,即指向第二个常量。
那么就从0x0000000D开始,看第二个常量,标志位为0x01,由表6-3可知该常量是UTF-8编码的字符串。这里使用的是UTF-8缩略编码,区别是:从’\u0001’到’\u007f’之间的字符(相当于1~127的ASCII码)的缩略编码使用一个字节表示, 从’\u0080’到’\u07ff’之间的所有字符的缩略编码用两个字节表示,从’\u0800’开始到’\uffff’之间的所有字符 的缩略编码就按照普通UTF-8编码规则使用三个字节表示。(其实就是省略所有前面的0)

由表6-5,可以从偏移位0x0000000E开始,看该字符串的length,为0x001D,即29。往后29 个字节正好都在1~127的ASCII码范围以内,内容为“org/fenixsoft/clazz/TestClass
可以使用javap指令输出常量表,由输出的常量对比,发现分析的两个常量都是正确的。

像常量表中的如“I”“V”“”这些,在程序中并没有,它们是由编译器自动生成的,是用来描述一些不方便用固定字节描述的内容的。
3、访问标志
在常量池结束后,后面两个字节是访问标志。访问标志代表着该类或接口的访问信息

比如6-1中的代码,TestJava是一个普通的Java类。它被public修饰,并且使用了JDK1.2之后的编译器进行编译,所以它的access_flag应该是0x0001|0x0020=0x0021
相关文章:
JVM的故事——类文件结构
类文件结构 文章目录 类文件结构一、概述二、无关性基石三、Class类文件的结构 一、概述 计算机是只认由0、1组成的二进制码的,不过随着发展,我们编写的程序可以被编译成与指令集无关、平台中立的一种格式。 二、无关性基石 对于不同平台和不同平台的…...
springboot自定义表格(动态合并单元格)
一、需求展示(一个订单多个商品,商品数量不限订单行合并) 二、技术选型(jxls自定义模板) <!-- 版本具体看官网Release,这里我们使用 2.13.0 --><dependency><groupId>org.jxls</group…...
C++零碎记录(二)
3. 调用其他类 3.1 类中有其他的类 #include <iostream> using namespace std;//点和圆关系案例//点类 class Point { public://设置xvoid setX(int x){m_X x;}//获取xint getX(){return m_X;}//设置yvoid setY(int y){m_Y y;}//获取yint getY(){return m_Y;}private…...
数学建模:回归分析
🔆 文章首发于我的个人博客:欢迎大佬们来逛逛 数学建模:回归分析 文章目录 数学建模:回归分析回归分析多元线性回归案例 多项式回归一元多项式回归多元二项式回归 非线性回归逐步回归 回归分析 多元线性回归 案例 首先进行回归分…...
数据库(一)
数据库 1.为什么要使用数据库 如果要存储数据,我们是可以使用文件来存储数据的,但是使用文件管理数据有很多缺点,比如: 不安全,不利于管理,查询,如果要存储大量的数据,使用文件管理…...
【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:首先我们要知道后序遍历数组的最后一个元素必然是根节点,然后根据根节点在中序遍历数组中的…...
kali 安装cpolar内网穿透实现 ssh 远程连接
文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过cpolar 内网穿透软件实现ssh 远程连接kali! 1. 启动kali ssh 服务 默认新安装的kali系统会关闭ssh 连接服务,我们通…...
算法训练 第一周
一、合并两个有序数组 本题给出了两个整数数组nums1和nums2,这两个数组均是非递减排列,要求我们将这两个数组合并成一个非递减排列的数组。题目中还要求我们把合并完的数组存储在nums1中,并且为了存储两个数组中全部的数据,nums1中…...
软件评测师之码制
目录 一、机器数二、码制三、数的表示范围 一、机器数 机器数就是一个数在计算机中的二进制表示,计算机中机器数的最高位是符号位,正数符号位为0,负数符号位为1,机器数包含原码、反码和补码三种表示形式。 二、码制 表现形式数…...
ubuntu18安装cmake27的方法
背景是ubuntu18默认的cmake是3.10 $ apt search cmake Sorting... Done Full Text Search... Done bear/bionic,bionic 2.3.11-1 allgenerate compilation database for Clang toolingcatkin/bionic,bionic 0.7.8-1 allLow-level build system macros and infrastructure for …...
通讯编程006——NodeJS OPC UA Client开发简单教程
本文介绍如何在NodeJS环境下开发OPC UA Client,通过本文可以对OPC UA的基本概念有所了解,掌握OPC UA的本质。相关软件请登录网信智汇(wangxinzhihui.com)。 开发步骤如下: 1)首先需要安装nodejs,要求版本至少是12。 …...
「高等数学」雅可比矩阵和黑塞矩阵的异同
「高等数学」雅可比矩阵和黑塞矩阵的异同 雅可比矩阵,Jacobi matrix 或者 Jacobian,是向量值函数( f : R n → R m f:\mathbb{R}^n \to \mathbb{R}^m f:Rn→Rm)的一阶偏导数按行排列所得的矩阵。 黑塞矩阵,又叫海森矩…...
继承(个人学习笔记黑马学习)
1、基本语法 #include <iostream> using namespace std; #include <string>//普通实现页面//Java页面 //class Java { //public: // void header() { // cout << "首页、公开课、登录、注册...(公共头部)" << endl; // } // void footer() …...
ToBeWritten之ATTCK 测评方案
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
JSONUtil详解
JSONUtil是一个通用的JSON工具类,用于在Java中操作JSON数据。虽然之前提到的示例中没有直接提及JSONUtil,但可以解释一下可能存在的一些常见JSON操作方法,这些方法通常可以在不同的JSON工具类中找到。 JSONUtil中的一些常见方法包括…...
ArcGIS Maps SDK for JS(一):概述与使用
文章目录 1 概述2 如何使用ArcGIS Maps SDK for JavaScript2.1 AMD 模块与 ES 模块2.2 AMD 模块和 ES 模块比较 3 几种安装方式3.1 通过 ArcGIS CDN 获取 AMD 模块3.2 通过 NPM 运行 ES 模块3.3 通过 CDN 获取 ES 模块3.4 本地构建 ES3.5 本地构建 AMD 3 VSCode下载与安装2.1 下…...
【STM32】FSMC接口的复用和非复用
问题背景 在阅读《零死角玩转STM32—F103指南者》,以及《STM32F10x-中文参考手册》关于FSMC一章节的时候,对于在控制NOR/SRAM的时候使用到的引脚,在提到NOR器件的时候提到了地址复用和非复用接口,一时间没明白是什么东西。 结论 非复用模式…...
操作系统强化认识之Shell编程学习与总结
目录 1.Shell的概述 2.Shell脚本入门 3.变量 3.1.系统预定义变量 3.2.自定义变量 3.3.特殊变量 4.运算符 5.条件判断 6.流程控制 6.1.if判断 6.2.case语句 6.3.for循环 6.4.while循环 7.read读取控制台输入 8.函数 8.1.系统函数 8.2.自定义函数 9.正则表示式入…...
怎么用conda下载清华源的pytorch(自带cuda的版本)
1,添加镜像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...
【ES6】CommonJS模块和ES6模块
在JavaScript中,模块是一种将功能代码组织成逻辑单元的方式,以便在其他项目中重复使用。有两种主要的模块系统:CommonJS和ES6。 1、CommonJS 在CommonJS中,我们使用require来引入模块,使用module.exports来导出模块。…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
