接上文
------------------------------------
二、类文件结构
虚拟机不关注Class的来源是什么语言,它只要符合Class文件应有的结构就可以在Java虚拟机中运行。
1.Class类文件结构
Class文件是一组8位字节为基础的二进制流,各个数据项目严格按照顺序紧凑排列在Class文件中,中间没有添加任何分隔符。当遇到需要占用8位字节以上空间的数据项时,会按照高位在前的方式分割成若干个8位字节进行存储。
Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中只有2种数据类型:无符号数和表。
无符号数:属于基本数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数。无符号数可以用来描述数字、索引引用、数量值、或按UTF-8编码构成的字符串值。
表:由多个无符号数或其他表作为数据项构成的复合数据类型,所有表都习惯性的以_info结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。
Class文件格式:
u4 magic 数量1
u2 minor_version 数量1
u2 major_version 数量1
u2 constant_pool_count 数量1
cp_info constant_pool 数量constant_pool_count-1
u2 access_flags 数量1
u2 this_class 数量1
u2 super_class 数量1
u2 interfaces_count 数量1
u2 interfaces 数量interfaces_count
u2 fields_count 数量1
field_info fields 数量fields_count
u2 methods_count 数量1
method_info methods 数量methods_count
u2 attributes_count 数量1
attribute_info attributes 数量attributes_count
(1)魔数与Class文件版本:
每个Class文件头4个字节称为魔数,唯一作用是确定这个文件是否能被虚拟机接受的Class文件。
因为使用文件扩展名可以很随意地被改动,使用魔数而不是扩展名来进行识别主要是基于安全考虑,只要这个魔数值还没有被广泛用过而引起混淆即可。
Class文件的魔数值为:0xCAFEBABE
紧接着魔数的4个字节存储的是Class文件版本号:第5和第6字节是次版本号,第7和第8字节是主版本号。
高版本JDK可以向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生变化。
JDK1.5 主版本号 49 \ JDk1.6 主版本号 50
(2)常量池constant_pool:
紧接着主次版本号的是常量池入口,常量池是Class文件结构中与其它项目关系最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时是Class文件中第一个出现的表类型数据。
由于常量池的数量不固定,所以在常量池入口需放置一项u2类型的数据,代表常量池容量计数值。这个容器计数是从1而不是从0开始的。Class文件格式规范将第0项常量空出来是有特殊考虑的,这样为了满足后面某些指向常量池的索引值的数据在特定情况下需要表达"不引用任何一个常量池项目"的意思。
只有常量池容量计数是从1开始的,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都与一般习惯相同,是从0开始的。
常量池主要存放2大类常量:字面量和符号引用。
字面量:如文本字符串、被声明为final的常量值。
符号引用:类和接口全限定名、字段名称和描述符、方法名称和描述符。
虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析并翻译到具体的内存地址之中。
常量池中每一项常量都是一个表,共有11种结构各不相同的表结构数据,者11种表都有一个共同的特点。即使表开始的第一位是一个u1类型的标志位(取值为1-12,缺少标志为2的数据类型),代表当前这个常量属于哪种常量类型。
在JDK的bin目录中,有一个专门用于分析Class文件的字节码的工具javap:
javap -verbose TestClass
(3)访问标志access_flags:
在常量池结束之后,紧接着的2个字节代表访问标志,这个标志用于识别一些类或接口层次的访问信息。包括:这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型。如果是类的话,是否被声明为final,等等。
(4)类索引、父类索引与接口索引集合:
类索引和父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据的集合,Class文件中由这3项数据来确定这个类的继承关系。
Java不允许多重继承,所以父类索引只有一个,除了java.lang.Object之外,所有Java类都有父类,父类的索引都不为0。接口索引集合就用来描述这个类实现了哪些接口,这些被实现的接口将按implements语句后的接口顺序从左到右排列在接口的索引集合中。
类索引、父类索引和接口索引集合都按顺序排列在访问标志之后,类索引和父类索引用两个u2类型的索引值表示。对于接口索引,入口第一项为u2类型的数据为接口计数器,表示索引表的容量。如果该类没有实现任何接口,那么该计数器值为0。,后面接口的索引表不再占用任何字节。
(5)字段表集合:
字段表用于描述接口或类中声明的变量。
字段包括了类级变量或实例级变量,但不包括在方法内部声明的变量。
(6)方法表集合。
相关推荐
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
本文将深入探讨JVM中的访问控制器,主要基于“java之jvm学习笔记十一(访问控制器)-源码”这一主题,以及相关的源码分析。 首先,我们得了解Java的安全模型。Java安全模型基于一种称为安全管理器(SecurityManager)...
Java虚拟机(JVM)是Java程序运行的基础,它提供了执行环境和内存管理。本文将深入探讨JVM的内存结构,特别是程序计数器、虚拟机栈、本地方法栈、堆内存以及它们在多线程环境下的工作原理。 程序计数器是JVM内存...
JVM学习笔记(缓慢更新).md
JVM的学习可以从其基本结构、代码编译和执行过程,以及内存管理和垃圾回收机制三个方面进行深入探讨。 首先,JVM的基本结构分为逻辑结构和物理结构。逻辑结构主要包括Java源码编译器、JVM执行引擎、类加载器等组件...
本篇JVM学习笔记主要关注对象声明、相关内存分配方法以及虚拟内存的物理和虚拟寻址概念。 首先,我们来看对象声明。在Java中,对象是在堆上创建的。例如,`CHeapObj` 类展示了如何在C++中模拟Java对象在堆上的分配...
**JVM学习笔记(Java虚拟机)** Java虚拟机(JVM)是Java语言的核心组成部分,它是Java程序运行的平台,负责解释和执行字节码。深入理解JVM对于优化Java应用程序性能至关重要。本笔记将从以下几个方面详细介绍JVM:...
"jvm视频及笔记"这个资源显然是一份全面学习JVM的材料,结合了视频教程和书面笔记,帮助学习者深入理解JVM的工作原理及其在实际开发中的应用。 JVM的学习可以从以下几个重要的知识点开始: 1. **JVM架构**:JVM...
《深入理解JVM:垃圾回收与优化》 在Java编程领域,JVM(Java Virtual Machine)扮演着至关重要的角色,它是Java程序...开发者需要不断学习和实践,才能在实际项目中有效地配置和优化JVM,确保程序的高效稳定运行。
这个资料包不仅涵盖了理论知识,还包含个人的学习笔记,对于学习和掌握JVM的各个方面都将大有裨益。无论是初学者还是经验丰富的开发者,都可以从中找到提升自己技能的宝贵资源。通过深入学习和实践,可以更好地理解...
### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...
### JVM中篇笔记知识点 #### 一、Class 文件结构 ##### 1. 概述 - **字节码文件的跨平台性** - Java 的跨平台性体现在 "Write Once, Run Anywhere" (WORA),即一次编写,到处运行。Java 语言编写的源代码在编译...
Java虚拟机(JVM)是Java程序运行的基础,它是一个抽象的计算机系统,负责执行Java字节码。本文将深入探讨JVM的工作...这本《JVM工作原理学习笔记》应包含了这些内容的详细讲解,对于学习和提升JVM相关知识极具价值。
NULL 博文链接:https://cooldatabase.iteye.com/blog/634599
Java8 Jdk JVM学习笔记、jdk1.8、SpringBoot; 主要内容为 JVM 内存与垃圾回收、类加载子系统、运行时数据区、本地方法等。适合开发1-3年想对JVM学习的同学。 在之后的开发中,更加详细的了解JVM,可以进行JVM问题...
《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...
本文将深入探讨JVM中的访问控制器,并通过分析"java之jvm学习笔记十一(访问控制器) -源码"中的`MySecurityManager`来进一步理解其工作原理。 访问控制器的主要任务是对类、方法和字段的访问进行限制,防止恶意代码...