JVM专题——类文件结构

本文部分内容节选自Java Guide和《深入理解Java虚拟机》, Java Guide地址: https://javaguide.cn/java/jvm/class-file-structure.html

🚀 基础(上) → 🚀 基础(中) → 🚀基础(下) → 🤩集合(上) → 🤩集合(下) → 🤗JVM专题1 → 🤗JVM专题2 → 🤗JVM专题3

Class 类文件结构

Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符, 这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据, 没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储。

ClassFile 结构如下

ClassFile {u4             magic; //Class 文件的标志u2             minor_version;//Class 的小版本号u2             major_version;//Class 的大版本号u2             constant_pool_count;//常量池的数量cp_info        constant_pool[constant_pool_count-1];//常量池u2             access_flags;//Class 的访问标记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];//属性表集合
}

魔数与Class文件版本号

每个Class文件的头四个字节被称为 魔数 , 它用来判断这个文件是否是一个能够被Java虚拟机接收的Class文件. Java虚拟机规定魔数必须是 0xCAFEBABE , 否则虚拟机会拒绝加载这个Class文件

紧接着魔数的四个字节是 Class文件的版本号 , 第5和第6字节是 次版本号 , 第7和第8字节是 主版本号 . 高版本的JDK能够向下兼容低版本的Class文件, 但是低版本的JDK不能向上兼容高版本的Class文件

常量池

紧接着魔数和Class文件版本号之后的是 常量池入口 . 常量池可以比喻为Class文件中的资源仓库, 它是Class文件结构中与其他项目关联最多的数据, 同时也是占用Class文件空间最大的数据项目之一, 另外它还是Class文件中第一个出现的表类型数据项目

    u2             constant_pool_count;//常量池的数量cp_info        constant_pool[constant_pool_count-1];//常量池

常量池的数量是 constant_pool_count - 1 (常量池计数器是从1开始计数的, 常量池索引为0表示 “不引用任何一个常量池项”)

常量池中主要存放两大类常量: 字面量符号引用 . 字面量比较接近于 Java 语言中的常量概念, 而符号引用属于编译原理的概念, 主要包括以下几类变量

  • 被模块导入或者开放的包
  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符
  • 方法句柄和方法类型
  • 动态调用点和动态常量

常量池中每一个常量都是一个表, 到JDK13版本目前有17个不同类型的常量

类型标志描述
CONSTANT_Utf8_info1UTF-8编码的字符串
CONSTANT_Integer_info3整型字面量
CONSTANT_Float_info4浮点型字面量
CONSTANT_Long_info5长整型字面量
CONSTANT_Double_info6双精度浮点型字面量
CONSTANT_Class_info7类或接口的符号引用
CONSTANT_String_info8字符串类型字面量
CONSTANT_Fieldref_info9字段的符号引用
CONSTANT_Methodref_info10类中方法的符号引用
CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
CONSTANT_NameAndType_info12字段或方法的部分符号引用
CONSTANT_MethodHandle_info15表示方法句柄
CONSTANT_MethodType_info16表示方法类型
CONSTANT_Dynamic_info17表示一个动态计算常量
CONSTANT_InvokeDynamic_info18表示一个动态方法调用点
CONSTANT_Module_info19表示一个模块
CONSTANT_Package_info20表示一个模块中开放或者导出的包

访问标志

在常量池结束之后, 紧接着的2个字节代表 访问标志 , 用于识别一些类或者接口层次的访问信息, 包括: 这个Class是类还是接口; 是否为 public 或者abstract; 如果是类的话, 是否被声明为 final

标志名称标志值含义
ACC_PUBLIC0x0001是否为public
ACC_FINAL0x0010是否为final
ACC_SUPER0x0020是否使用invokespecial字节码指令的新语义
ACC_INTERFACE0x0200是否是一个接口
ACC_ABSTRACT0x0400是否为abstract
ACC_SYNTHETIC0x1000标识这个类并非由用户代码产生的
ACC_ANNOTATION0x2000标识这是一个注解
ACC_ENUM0x4000标识这是一个枚举
ACC_MODULE0x8000标识这是一个模块

类索引, 父类索引和接口索引集合

类索引, 父类索引和接口索引都按顺序排列在访问标志之后, 类索引和父类索引用两个u2类型的索引值表示, 它们各自指向一个类型为CONSTANT_Class_info的类描述符常量, 通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在 CONSTANT_Utf8_info类型的常量中的全限定名字符串

    u2             this_class;//当前类u2             super_class;//父类u2             interfaces_count;//接口数量u2             interfaces[interfaces_count];//一个类可以实现多个接口

类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,由于 Java 语言的单继承,所以父类索引只有一个,除了 java.lang.Object 之外,所有的 Java 类都有父类,因此除了 java.lang.Object 外,所有 Java 类的父类索引都不为 0。

字段表集合

字段表用于描述接口或类中声明的变量. 字段包括类级变量以及实例变量, 但不包括在方法内部声明的局部变量

    u2             fields_count;//字段数量field_info     fields[fields_count];//一个类会可以有个字段

字段表结构

field_info {u2		access_flags;u2		name_index;u2		descriptor_index;u2		atributes_count;attribute_info		attributes[attributes_count];
}
  • access_flags : 字段的作用域 (public , private , protected 修饰符), 是实例变量还是类变量, 可否被序列化, 可变性( final 修饰 ) , 可见性(volatile)
  • name_index : 对常量池的引用, 表示的字段的名称
  • descriptor_index : 对常量池的引用, 标识字段和方法的描述符
  • attributes_count : 一个字段还会拥有一些额外的属性, attributes_count 存放属性的个数
  • attributes[attributes_count] : 存放具体属性具体内容

上述这些信息中, 各个修饰符都是布尔值, 要么有某个修饰符, 要么没有, 很适合使用标志位来表示. 而字段叫什么名字, 字段被定义为什么数据类型这些都是无法固定的, 只能引用常量池中常量来描述

方法表集合

Class文件存储格式中对于方法的描述和对字段的描述几乎是一模一样的, 方法表的结构如同字段表一样, 依次包括了访问标志, 名称索引, 描述符索引, 属性表集合等

    u2             methods_count;//方法数量method_info    methods[methods_count];//一个类可以有个多个方法

方法表结构

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

因为 volatiletransient 修饰符不能修饰方法, 所以方法表的访问标志中没有这两个对应的标志, 但是增加了 synchronized , native , abstract 等关键字修饰方法, 所以也就多了这些关键字对应的标志

属性表集合

   u2             attributes_count;//此类的属性表中的属性数attribute_info attributes[attributes_count];//属性表集合

与 Class 文件中其他的数据项目要求严格的顺序, 长度, 内容不同, 属性表集合的限制稍微宽松一点, 不再要求各个属性表具有严格的顺序, 并且Java虚拟机规范允许只要不与已有属性名重复, 任何人实现的编译器都可以向属性表中写入自己定义的属性信息, Java虚拟机运行时会忽略掉它不认识的属性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/793740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Java面试自救指南》(专题二)计算机网络

文章目录 力推的计网神课get请求和post请求的区别在浏览器网址输入一个url后直到浏览器显示页面的过程常用状态码session 和 cookie的区别TCP的三次握手和四次挥手七层OSI模型(TCP/IP协议模型)各种io模型的知识http协议和tcp协议的区别https和http的区别…

京准、ntp校时服务器(GPS北斗卫星校时器)技术方案

京准、ntp校时服务器(GPS北斗卫星校时器)技术方案 京准、ntp校时服务器(GPS北斗卫星校时器)技术方案 四分天下目前,全球的 GPS卫星同步系统处于“四分天下”状态,以美俄两国的系统处于领导地位&#xff0c…

【Unity每日一记】如何让Sprite精灵图集的背景图层变成透明,方便切割

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

【电路笔记】-逻辑或门

逻辑或门 文章目录 逻辑或门1、概述2、2 输入晶体管或门3、数字逻辑或门类型逻辑或门是一种数字逻辑电路,仅当其一个或多个输入为高电平时,其输出才会变为高电平至逻辑电平 1。 1、概述 “逻辑或门”的输出 Q 仅当其所有输入都处于逻辑电平“0”时才再次返回“低”。 换句话…

《CSS入门到精通》结语

1. CSS学习资源推荐: 进一步探索CSS及前端技术的世界,可以从以下几个高质量的学习资源和社区入手: 在线课程: W3Schools:提供了详尽的CSS教程和实践示例。 Codecademy、FreeCodeCamp:包含互动性强的CSS课程…

Pygame基础10-物理模拟

PyMunk PyMunk是一个模拟物理的库。 注意,PyMunk只是进行物理模拟,不包含可视化的功能。如果需要可视化,可使用pygame等库。 可用pip安装pymunk pip install pymunk pymunk中的概念: space: 物理空间。 包含gravity 模…

爬虫 知识点2以及SSL1129错误该怎么解决

article_url url_tag[href]article_response requests.get(article_url, headersheaders)article_soup BeautifulSoup(article_response.content, "html.parser")print(index)(1)article_url url_tag[‘href’] 这行代码从一个名为url_tag…

AJAX —— 学习(一)

目录 一、原生 AJAX (一)AJAX 介绍 1.理解 2.作用 3.最大的优势 4.应用例子 (二)XML 介绍 1.理解 2.作用 (三)AJAX 的特点 1.优点 2.缺点 二、HTTP 协议 (一)HTTP 介…

C语言中的结构体:揭秘数据的魔法盒

前言 在C语言的广阔天地中,结构体无疑是一颗璀璨的明珠。它就像是一个魔法盒,能够容纳各种不同类型的数据,并按我们的意愿进行组合和排列。那么,这个魔法盒究竟有何神奇之处呢?让我们一探究竟。 一、结构体的诞生&…

Java学习14(异常)

异常 概述 程序运行过程出错的情况就是异常。Java提供了异常处理机制,出现不正常情况的时候,就会把异常信息打印到控制台,供程序员参考修改。 这是Java打印的异常信息,这个信息是JVM打印的。 异常的作用: 增强程序的健…

FOC算法中为啥用PWM触发ADC中断

在FOC(Field Oriented Control,场向量控制)算法中,为什么要使用PWM(Pulse Width Modulation,脉宽调制)触发ADC(Analog-to-Digital Converter,模数转换器)中断…

可以写网易云的了!

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 1枚程序媛,大专生,2年时间从1800到月入过万,工作5年买房。 分享成长心得。 259篇原创内容-gzh 后台回复“前端工具”可获取开发工具,持续更新中…

设计模式——原型模式05

原型模式核心复制,每次new出来的对象完全不一样,实现对象之间的隔离。 学习前最好先掌握jAVA值传递和深浅拷贝 设计模式,一定要敲代码理解 浅拷贝 克隆出对象,其中两者的引用类型属性是同一个对象。 对象信息 /*** author ggb…

常用的AI绘画自动生成器介绍

AI绘画自动生成器是一种利用人工智能技术生成图像的工具。它可以根据用户输入的文本描述自动生成相应的图像。目前,有几种流行的AI绘画自动生成器,包括: 1. **DALL-E 2** DALL-E 2是由OpenAI开发的AI绘画生成器,它可以根据用户输入的自然语言描述生成高质量的图像。DALL-E 2使…

【Linux】Linux进程学习(基本认知)

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 前言一、冯诺依曼体系二、系统管理三、进程理解3.1 代码与数据3.2 进程控制块 四…

jvm总结学习

四种加载器 1.启动类加载器 2.拓展类加载器 3.应用程序加载器 4.自定义加载器 沙箱机制 就是为了保证安全,增加的一些权限。 native方法区(静态变量,常量,类信息(构造方法,接口定义)&…

java八股——常见设计模式

上一篇传送门:点我 有哪些设计模式? 按照模式的应用目标分类,可以分为创建型模式、结构型模式、行为型模式三类。 创建型模式: 对象实例化的模式,创建型模式用于解耦对象的实例化过程。 单例模式:某个类…

突破!AI机器人拥有嗅觉!仿生嗅觉芯片研究登上Nature子刊

我们一直梦想着让AI与人类能够更加相似,赋予它们视觉与听觉。而让机器人拥有嗅觉一直以来面临着巨大的困难。 香港科技大学范志勇教授领导的研究团队凭借最新研发的仿生嗅觉芯片(BOC)在这一领域取得了重大突破。该研究成果目前已被发表到IF …

ActiViz中的数据集vtkPolyData

文章目录 前言一、数据结构二、数据内容三、几何操作四、数据导入与导出五、数据可视化六、函数详解1、SetPoints(vtkPoints points):2、SetPolys(vtkCellArray polys):3、GetNumberOfPoints():4、GetNumberOfCells():5、GetPointData():6、GetCellData():7、Ge

github生成新的SSH密钥

首先是参考官方文档 生成新的 SSH 密钥并将其添加到 ssh-agent述 当你在创建SSH密钥时遇到提示: Enter file in which to save the key (/c/Users/YOU/.ssh/id_ALGORITHM):这一步是让你选择保存生成的SSH密钥对的文件名和位置。如果你直接按回车键([Pr…