深入理解JVM - 类文件结构

【深入理解JVM】:Class类文件结构 概述我们平时在DOS界面中往往需要运行先运行javac命令,这个命令的直接结果就是产生相应的class文件,然后基于这个class文件才可以真正运行程序得到结果。自然。这是Java虚拟机的功劳,那么是不是Java虚拟机只能编译.java的源文件呢?答案是否定的。时至今日,Java虚拟机已经实现了语言无关性的特点。而实现语言无关性的基础是虚拟机和字节码的存储格式,Java虚拟机已经不和包括Java语言 阅读详情

详细请阅读《深入理解Java虚拟机》第六章节。

1、概述

平台无关性(Write Once ,Run anyWhere)、语言无关性(让其他语言运行在Java虚拟机之上,如Groovy、Scala、JRuby、Jython、Clojure等)的基础是虚拟机和字节码文件。Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联。


2、Class类文件的结构

Class 文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。
无符号数属于基本的数据类型,u1,u2,u4,u8来分别代表1、2、4、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表习惯以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质是一张表。
注意:Class文件不像XML等描述语言,由于它没有任何分隔符,无论是顺序还是数量,甚至于数据存储的字节序这样的细节,都是被严格限定的,哪一个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。

2.1、魔数与Class文件的版本

每个Class文件的头四个字节被成为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。很多文件存储标准中都使用魔数来进行身份识别,比如图片格式。
紧接着魔数的四个字节存储的是Class文件的版本号:第五和第六字节是次版本号,第七和第八是主版本号。Java版本号从45开始,JDK1.1之后的每一个JDK大版本发布主版本号都会向上加一(JDK1.0~JDK1.1使用了45.0~45.3的版本号),高版本号的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。例如JDK1.1能支持版本号为45.0~45.65535的Class文件,无法执行版本号为46.0以上的Class文件。

2.2、常量池

紧接着主次版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库,它是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时也是在Class文件中第一个出现的表类型数据项目。由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值。
常量池中主要存放两大类常量:字面量和符号引用。
字面量:接近于Java语言层面的常量概念,比如文本字符串、声明为final的常量值等。
符号引用:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。
Java代码在进行javac编译的时候,并不像c或c++那样有“连接”这一步骤,而是在虚拟机加载Class文件的时候进行动态连接。也就是说,在Class文件中不会保存各个方法、字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换的话无法得到真正的内存入口,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址中。
常量池中的每一项常量都是一个表。JDK1.7中共有14种结构各不相同的表结构数据,这14种表都有一个共同的特点。就是表开始第一位是一个u1类型的标志位,代表当前的这个常量是哪一种常量类型。

Java中如果定义了超过64KB(65535)英文字符的变量或者方法名,将无法编译。由于Class文件中的方法、字段等都需要引用CONSTANT_Utf8_info行常量来描述名称,所以CONSTANT_Utf8_info型常量的最大长度也就是Java中方法、字段名的最大长度。而这里的最大长度就是u2类型能表达的最大值65535.

2.3、访问标志

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

2.4、类索引、父类索引与接口索引集合

类索引和父类索引都是一个u2类型的数据,而接口索引是一组u2类型的数据的集合,Class文件中由这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。由于Java语言不允许多重继承,所以父类索引只有一个,除了java.lang.Object之外,所有的Java类都有父类,因此除了java.lang.Object外,所有Java类的父类索引都不为0。接口索引集合用来描述这个类实现了哪些接口,这些被实现的接口将按implements语句后的接口顺序从左到右排列在接口索引集合中。
类索引、父类索引和接口索引集合都按照顺序排列在访问标志之后,类索引和父类索引用两个u2类型的索引值表示,它们各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在CONSTANT_Utf8_info类型的常量中的全限定名字符串,

2.5、字段表集合

字段表用于描述接口或类中声明的变量。字段包括类级变量和实例级变量,但不包括在方法内部声明的局部变量。字段的信息:作用域(private 、public、protected)、可变性(final)、并发可见性(volatile,是否强制从主内存读取)、字段类型(基本类型、对象、数组)、是否可序列化(transient)、字段名称、是类变量(static)还是实例变量。上述这些信息中,各个修饰符都是布尔值,要么有某个修饰符要么没有。而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。
这里有一个概念需要了解:描述符。描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符的规则,基本数据类型(byte、short、int、long、float、double、char、boolean)以及代表无返回值的void类型都用一个大写的字符表述,而对象类型用字符L加对象的全限定名来表示。
如下图所示,字段表(方法表与字段表的结构一样)的结构:


2.6、属性表

在Class文件、字段表、方法表、都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
Code属性:Java程序方法体中的代码经过javac编译器处理后,最终变为字节码指令存储在Code属性内。
Exceptions属性:列举出方法中可能抛出的受检查异常,也就是方法描述时在throws关键字后面列举的异常。
LineNumberTable属性:描述Java源码行号与字节码行号之间的对应关系。
LocalVariableTable属性:用于描述栈帧中局部变量表中的变量与Java源码中定义的变量之间的关系。
SourceFile属性:用于记录生成这个Class文件的源码文件名称。
ConstantValue:通知虚拟机自动为静态变量赋值。
InnerClass属性:记录内部类与宿主类之间的关联;如果一个类中定义了内部类,那编译器将会为它以及所包含的内部类生成InnerClass属性。
Deprecated以及Synthetic属性:
Deprecated:表示不推荐使用。
Synthetic:代表此字段或者方法并不是由Java源码产生的,而是编译器自行添加的。
StackMapTable属性:这个属性会在虚拟机类加载的字节码验证阶段被新类型检查验证器使用,目的在于代替以前比较消耗性能的基于数据流分析的类型推导验证器。该验证器在JDK1.6中首次使用,并在JDK1.7中强制代替原本基于类型推断的字节码验证器。
signatrue:在JDK1.5中大幅增强了Java语言的语法,在此之后,任何类、接口、初始化方法或成员的泛型签名如果包含了类型变量或者参数化类型,则signature属性会为它记录泛型签名信息。
BootstrapMethods属性:用于保存invokeddynamic指令引用的引导方法限定符。
V-REP(Cooprliesim EDU)自学笔记 实现UR5机械臂末端按轨迹移动 阅读详情

相关推荐

从末流211到东南软院:一个普通CS学生的保研逆袭全记录(含GPA、竞赛、面试避坑点)

本文详细记录了一位来自末流211院校的CS学生如何通过合理规划和持续努力,成功保研东南大学软件学院的完整历程。文章分享了GPA提升、竞赛策略、夏令营申请和预推免准备等关键环节的实战经验,特别强调了竞赛在弥补科研短板中的重要作用,为普通背景学生提供了可复制的保研逆袭方案。

weixin_33417488的博客 392

JVM——类文件结构

Java诞生之初的口号:“一次编写,到处运行(Write Once, Run Anywhere)”。 各个平台的虚拟机与所有平台都同意使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石。实现语言无关性的基础人生是虚拟机和字节码存储格式。Java虚拟机不和包括Java在内的如何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了Java虚拟机指...

Richard331的博客 1174

数字图像处理基础实验(二):直方图均衡化

一、实验内容及原理 1、计算灰度图像的归一化直方图 具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来 步骤: (1)初始化一个256大小的数组,存放图像中每级灰度值的像素点的个数 (2)遍历整张图像 (3)归一化数组 2、灰度图像直方图均衡处理 具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。 步骤: (1)读取该像素点的灰度值 (...

lyd1995的博客 4527

深入探索JVM类文件结构 — Class类文件的结构(一)

任何一个Class文件都对应着唯一的一个类或接口的定义信息,但是反过来说,类或 接口并不一定都得定义在文件里(譬如类或接口也可以动态生成,直接送入类加载器中)。本章中, 笔者只是通俗地将任意一个有效的类或接口所应当满足的格式称为“Class文件格式”,实际上它完全不 需要以磁盘文件的形式存在。

cupkss的博客 144

ANSYS Fluent 2023R2实战:用欧拉多相流模型搞定流化床模拟(附详细参数避坑)

本文详细解析了ANSYS Fluent 2023R2中欧拉多相流模型在流化床模拟中的应用,包括模型选择、材料属性设置、相间作用力配置及初始化技巧。特别针对高颗粒浓度工况提供参数优化方案,帮助工程师提升模拟精度与效率,适用于化工、能源等领域的流化床反应器设计。

weixin_30938149的博客 269

STM32L476低功耗实战:LPTIM精准定时唤醒STOP2模式与系统级功耗优化

本文深入探讨了STM32L476低功耗实战技巧,重点解析了LPTIM精准定时唤醒STOP2模式的配置与优化。通过详细的步骤指南和实战经验分享,帮助开发者实现系统级功耗优化,特别适合电池供电设备开发。文章涵盖LPTIM1定时器配置、STOP2模式进入流程及常见问题排查,助力将整机功耗降至8.2uA级别。

weixin_33686714的博客 436

【JavaSE】十九、JVM运行流程 && 类加载Class Loading

JVM内存分为五大区域: 程序计数器:线程私有,存储下条指令地址 虚拟机栈:线程私有,存储方法调用栈帧 本地方法栈:线程私有,支持Native方法调用 堆:线程共享,存储对象实例,GC主要区域 方法区:线程共享,存储类元信息(Java8后改为元空间) JVM运行流程: 类加载:加载→验证→准备→解析→初始化 执行引擎:解释执行与JIT编译结合 内存管理:运行时数据区维护程序状态 本地接口:支持JNI调用 垃圾回收:自动管理堆内存 类加载过程严格遵循五阶段顺序,确保类安全正确地加

lirendada的博客 1785

【SpringBoot 3.x 第57节】Spring Boot 3 启动快得不讲武德?揭秘 Spring AOT 编译引擎背后的真相!

🏆本文收录于《滚雪球学SpringBoot 3》,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。    本专栏致力打造最硬核 SpringBoot3 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot3教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。    若还想学习更多,可直接前往《滚雪球学SpringBoot(全版本合集)》,涵盖SpringBoot所有版本教学文章

**My Coding Family** 1760

Java 中的 File 文件类(四千字超全详解)

博主将用 优快云 记录 Java 后端开发学习之路上的经验,并将自己整理的编程经验和知识分享出来,希望能帮助到有需要的小伙伴。博主也希望和一直在坚持努力学习的小伙伴们共勉!唯有努力钻研,多思考勤动手,方能在编程道路上行至所向。由于博主技术知识有限,博文中难免会有出错的地方,还望各位大佬包涵并批评指正,博主会及时改正;如果本文对小伙伴你有帮助的话,求求给博主一个赞支持一下,可以一起交流,一起加油!!

林二月的博客 8084

基于Python的彩票数据爬虫:数据抓取与趋势分析

爬虫是一种用于从互联网上自动抓取信息的程序。在抓取彩票数据时,我们首先需要确定目标网站并获取其网页内容,接着提取彩票的开奖结果信息并保存。彩票数据通常是以HTML表格或列表的形式展示,爬虫可以利用Python的requests和来抓取静态网页,或使用Selenium来抓取动态页面。在本篇博客中,我们深入探讨了如何使用Python编写彩票数据爬虫,抓取并分析彩票开奖结果。通过Python爬虫技术,结合数据分析与可视化工具,我们能够全面分析历史开奖数据,揭示彩票号码的频率分布、趋势变化以及未来的可能走势。

2201_76125261的博客 1939

【深度解析】解决 NVIDIA 显卡“掉卡”与 Xid 79 错误:开启持久化模式 (Persistence Mode)

【深度解析】解决 NVIDIA 显卡“掉卡”与 Xid 79 错误:开启持久化模式 (Persistence Mode)

Edward的博客 865

深入理解JVM-类文件结构

你未必出类拔萃,但一定与众不同 类文件结构 文章目录类文件结构概述Class类文件的结构魔数与Class文件的版本常量池访问标志类索引,父类索引和接口索引集合字段表集合方法表集合属性表集合 概述 由于最近十年内虚拟机以及大量建立在虚拟机之上的程序语言如雨后春笋一般出现,把我们编写的程序编译成二进制本地机器码已经不在是唯一选择 越来越多的语言选择了与操作系统和机器指令集无关的格式作为编译后的存储格式 Java语言中的各种语法,关键字,。常量变量和运算符号的语义最终都会由多条字节码指令组合来表达。 Cla.

qq_44752800的博客 1147

9、硬件工程师笔试面试知识器件篇——三极管(2025版本)

本文全面介绍了三极管的基础知识与应用,包括其结构、类型、工作原理、工作状态、功能、应用场景及特性参数。详细探讨了三极管在信号放大、无线通信、音频设备及医疗设备中的具体应用,并深入分析了设计放大电路时如何平衡增益与噪声、优化偏置电路以提高稳定性、使用负反馈改善性能等关键问题。此外,文章还涵盖了高频电路设计、温度补偿策略、电磁干扰防护等实用内容,为硬件工程师提供了全面的技术参考和设计指导。

XU157303764的博客 7314

深入理解JVM:类文件结构

一、 在java诞生的时候就有一个口号:“一次执行,到处运行!”。字节码实现了这部分功能。 注意:JVM不和包括java在内的任何语言绑定,它只与Class文件这种特定的二进制文件格式所关联。 其他语言可以通过编译器生成字节码文件,然后再jvm上面运行。 二、Class文件 任何一个Class文件都对应这唯一一个类或者接口的定义信息,但反过说不正确。 Class文件是一组以8位字节...

Zystem 287

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

《深入理解JVM》第六章 类文件结构

-

给时光以生命 337

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

深入理解JVM - 类文件的结构

Class类文件的结构 Class文件是以8个字节为单位的二进制流,由魔数、版本号、常量池、类信息、父类信息、接口表、字段表、方法表和属性表组成。下图清晰的展示了Class文件字节码结构。 Class文件是如何组成的 接下来会用一段简单的Java代码为示例来讲解Class文件是如何组成的? 一段简单的Java代码 public class Hello { private static fin...

xiangliqu的专栏 476

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

深入理解JVM 第六章 类文件结构

深入理解JVM 第六章 类文件结构Class类文件的结构1 魔数与Class文件的版本2 常量池 Class类文件的结构 Class文件是一组以8为字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有任何分隔符,这使得整个Class文件中存储的内容全都是程序运行的必要数据,没有空隙存在。当遇到8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。 根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构

Seven_Year1的博客 340

深入理解JVM虚拟机(六)类文件结构

深入理解JVM虚拟机(六)类文件结构 一 概述 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新...

Tong_Nan的博客 240

《深入理解JVM》第六章类文件结构

JVM的两个目标:平台无关性与语言无关性。 平台无关性: 由于有字节码这个中间商,所以可以实现跨平台,实现一次编写到处运行的目的,那么代价是什么呢?成为半编译半解释语言,比同等直接编译的语言略慢不过也能接受。 语言无关性: JVM可不止能够运行Java啊,还能跑很多其他的语言,反正大家编译出来的class文件都差不多。JVM本质是执行class字节码,不管啥语言多写个编译器就好了。 类文件结构 啊这部分太难啃了,我比较倾向于如书中所说读字典的方式。不过它又很重要。所以我只记录我认为信息量比较大的吧(当然不

qq_38732834的博客 323

JVM的类文件结构,深入理解JVM必须趟过去的坎

阅读本章时,大概会不可避免地感到 比较枯燥,但这部分内容又是Java虚拟机的重要基础之一,是了解虚拟机的必经之路,如果想比较深 入地学习虚拟机相关知识,这部分是无法回避的。

eck_燃的博客 351

【深入理解JVM】Java类文件的基本结构

Java类文件(.class文件)是一个为已编译Java程序仔细定义的格式。Java源代码被编译成能够被任何JVM加载和执行的类文件。在被JVM加载之前,类文件可能是由网络传输而来。类文件是独立于底层平台的,所以适用于更多的地方。它们由简洁的JVM字节码组成,这样就能轻装上阵。类文件常常被压缩,以极快的速度通过网络,到达世界各地的JVM。类文件里有什么?Java类文件包含JVM需要知道的关于一个Ja

lmb55的专栏 782

深入理解 JVM(2)类文件结构

本文主要讲述 Java Class 文件结构及解析。

HappyFeet的博客 398

深入理解JVM - Class类文件的结构

Class文件是Java虚拟机执行引擎的数据入口,也是Java技术体系的基础支柱之一。 Class文件本质 Class文件本质上是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。 Class文件格式 Class文件格式采用一种类似于C语言结构体的伪结构...

xiaolyuh的专栏 738

深入理解Java虚拟机:Jvm总结-类文件结构以及类加载机制

代码编译的结果从本地机器码转变为字节码,冲破了平台界限。

Oceáno的博客 1497
上一篇: 深入理解JVM - 垃圾收集器与内存分配策略
下一篇: 并发编程实战 - 基础部分[对象的组合、基础构建模块]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值