JVM Class文件结构
每一个class文件对应于如下所示的结构体:
其中 u1,u2和u4是Class文件结构的私有数据类型,分别表示1个字节,2个字节和4个字节的无符号数
字段解释:
- magic
魔数,魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的Class文件。魔数值固定为0xCAFEBABE,不会改变。
- minor_version和major_version
副版本号和主版本号,minor_version和major_version的值分别表示Class文件的副、主版本。它们共同构成了Class文件的格式版本号。譬如某个Class文件的主版本号为M,副版本号为m,那么这个Class文件的格式版本号就确定为M.m。Class文件格式版本号大小的顺序为:1.5 < 2.0 < 2.1。
一个Java虚拟机实例只能支持特定范围内的主版本号(Mi至Mj)和0至特定范围内(0至m)的副版本号。假设一个Class文件的格式版本号为V,仅当Mi.0 ≤ v ≤ Mj.m成立时,这个Class文件才可以被此Java虚拟机支持。不同版本的Java虚拟机实现支持的版本号也不同,高版本号的Java虚拟机实现可以支持低版本号的Class文件,反之则不成立
major版本对应关系:
version | major | hex |
Java SE 9 | 53 | 0x35 |
Java SE 8 | 52 | 0x34 |
Java SE 7 | 51 | 0x33 |
Java SE 6.0 | 50 | 0x32 |
Java SE 5.0 | 49 | 0x31 |
JDK 1.4 | 48 | 0x30 |
JDK 1.3 | 47 | 0x2F |
JDK 1.2 | 46 | 0x2E |
JDK 1.1 | 45 | 0x2D |
- constant_pool-count
常量池计数器,constant_pool_count的值等于constant_pool表中的成员数加1。constant_pool表的索引值只有在大于0且小于constant_pool_count时才会被认为是有效的,对于long和double类型有例外情况
- constant_pool[]
常量池,constant_pool是一种表结构(§4.4),它包含Class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其它常量。常量池中的每一项都具备相同的格式特征——第一个字节作为类型标记用于识别该项是哪种类型的常量,称为“tag byte”。常量池的索引范围是1至constant_pool_count−1
- access_flags
访问标志,access_flags是一种掩码标志,用于表示某个类或者接口的访问权限及基础属性。access_flags的取值范围和相应含义:
ACC_PUBLIC:取值为0x0001
ACC_FINAL::取值为0x0010
ACC_SUPER:取值为0x0020,用于确定该Class文件里面的invokespecial指令使用的是哪一种执行语义。目前Java虚拟机的编译器都应当设置这个标志。ACC_SUPER标记是为了向后兼容旧编译器编译的Class文件而存在的,在JDK1.0.2版本以前的编译器产生的Class文件中,access_flag里面没有ACC_SUPER标志。同时,JDK1.0.2前的Java虚拟机遇到ACC_SUPER标记会自动忽略它
ACC_INTERFACE:取值为0x0200,表示是接口
ACC_ABSTRACT:取值为0x0400
ACC_SYNTHETIC:取值为0x1000, 表示并非Java源码生成的字节码
ACC_ANOTATION:0x2000,表示是注解
ACC_ENUM:取值为0x4000,表示是枚举
- this_class
类索引,this_class的值必须是对constant_pool表中项目的一个有效索引值。constant_pool表在这个索引处的项必须为CONSTANT_Class_info类型常量,表示这个Class文件所定义的类或接口
- super_class
父类索引,对于类来说,super_class的值必须为0或者是对constant_pool表中项目的一个有效索引值。如果它的值不为0,那constant_pool表在这个索引处的项必须为CONSTANT_Class_info类型常量,表示这个Class文件所定义的类的直接父类。当前类的直接父类,以及它所有间接父类的access_flag中都不能带有ACC_FINAL标记。对于接口来说,它的Class文件的super_class项的值必须是对constant_pool表中项目的一个有效索引值。constant_pool表在这个索引处的项必须为代表java.lang.Object的CONSTANT_Class_info类型常量。如果Class文件的super_class的值为0,那这个Class文件只可能是定义的是java.lang.Object类,只有它是唯一没有父类的类
- interfaces_count
接口计数器,interfaces_count的值表示当前类或接口的直接父接口数量
- interfaces[]
接口表,interfaces[]数组中的每个成员的值必须是一个对constant_pool表中项目的一个有效索引值,它的长度为interfaces_count。每个成员interfaces[i] 必须为CONSTANT_Class_info类型常量,其中0 ≤ i < interfaces_count。在interfaces[]数组中,成员所表示的接口顺序和对应的源代码中给定的接口顺序(从左至右)一样,即interfaces[0]对应的是源代码中最左边的接口。
- fields_count
字段计数器,fields_count的值表示当前Class文件fields[]数组的成员个数。fields[]数组中每一项都是一个field_info结构的数据项,它用于表示该类或接口声明的类字段或者实例字段
- fields[]
字段表,fields[]数组中的每个成员都必须是一个fields_info结构的数据项,用于表示当前类或接口中某个字段的完整描述。fields[]数组描述当前类或接口声明的所有字段,但不包括从父类或父接口继承的部分
- methods_count
方法计数器,methods_count的值表示当前Class文件methods[]数组的成员个数。Methods[]数组中每一项都是一个method_info结构的数据项
- methods[]
方法表,methods[]数组中的每个成员都必须是一个method_info结构的数据项,用于表示当前类或接口中某个方法的完整描述。如果某个method_info结构的access_flags项既没有设置ACC_NATIVE标志也没有设置ACC_ABSTRACT标志,那么它所对应的方法体就应当可以被Java虚拟机直接从当前类加载,而不需要引用其它类。method_info结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、实例初始化方法方法和类或接口初始化方法方法。methods[]数组只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法
- attributes_count
属性计数器,attributes_count的值表示当前Class文件attributes表的成员个数。attributes表中每一项都是一个attribute_info结构的数据项
- attributes[]
属性表,attributes表的每个项的值必须是attribute_info结构。在本规范里,Class文件结构中的attributes表的项包括下列定义的属性:InnerClasses、EnclosingMethod、Synthetic、Signature、SourceFile,SourceDebugExtension、Deprecated、RuntimeVisibleAnnotations、RuntimeInvisibleAnnotations以及BootstrapMethods属性。对于支持Class文件格式版本号为49.0或更高的Java虚拟机实现,必须正确识别并读取attributes表中的Signature、RuntimeVisibleAnnotations和 RuntimeInvisibleAnnotations属性。对于支持Class文件格式版本号为51.0或更高的Java虚拟机实现,必须正确识别并读取attributes表中的BootstrapMethods属性。本规范要求任一Java虚拟机实现可以自动忽略Class文件的attributes表中的若干(甚至全部)它不可识别的属性项。任何本规范未定义的属性不能影响Class文件的语义,只能提供附加的描述信息
相关推荐
### JVM加载Class文件详解 #### 一、Java与JVM中的Class文件加载机制概述 Java作为一种动态性极强的解释型编程语言,在程序运行时,Java虚拟机(JVM)负责将编译生成的`.class`文件加载到内存中进行执行。在Java...
Class文件的结构非常严谨,每个字段都有固定的含义,这对于JVM来说至关重要,因为它需要能够准确地解析并执行这些文件中的指令。 Class文件的主要组成部分包括:魔术码、版本号、常量池、访问标志、类索引、父类...
JVM-CLASS文件分析脑图的知识点涵盖了Java类文件的结构、组成、以及如何解析这些结构。class文件是Java虚拟机(JVM)能够识别和加载的二进制格式,它包含了一个Java类或者接口的定义。 首先,class文件以一个魔术数...
Class文件结构是JVM的核心组件之一,对于Java开发者来说,理解Class文件结构是非常重要的。本文将深入解释Class文件结构的详细信息,包括Class文件的组成部分、常量池、访问标志、类索引、字段表集合、方法表集合、...
JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java中的核心机制之一,由于Java中的所有类必须被装载到JVM中才能运行,这个装载工作是由JVM中的类装载器完成的。类装载器所做的工作实质是把类文件从硬盘...
另外,` jclasslib`是一款可视化的字节码查看器,它提供了更直观的方式查看和分析.class文件,包括类结构、常量池、字段和方法的详细信息。使用这样的工具可以帮助我们更好地理解JVM的内部工作原理。 此外,学习...
### Class文件结构组成详解 #### 一、Class文件概述 ...通过上述分析可以看出,Class文件结构设计严谨且高度组织化,使得JVM能够高效地加载和执行Java程序。理解这些细节有助于深入掌握Java编程语言和JVM的工作原理。
2. **类加载机制**:JVM使用类加载器(ClassLoader)将.class文件加载到内存中,类加载器体系结构包括Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,它们分别负责加载不同的类库。...
JavaClass文件的校验过程是为了确保加载到Java虚拟机(JVM)上的Class文件具有正确的内部结构,从而保障所定义类型的可用性和安全性,同时确保不同Class文件之间的一致性。Java文件校验器通过四次独立扫描完成校验...
类加载器负责将.class文件加载到JVM内存中。Java的类加载机制采用双亲委托模型,即先由父加载器尝试加载,如果失败再由子加载器进行加载。类加载器分为引导类加载器、扩展类加载器和应用程序类加载器,以及用户...
JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在...
### Class文件结构详解 #### 一、概述 `class`文件是Java编译器生成的目标文件格式,也是Java虚拟机执行的基本单位。每个`.class`文件代表了一个Java类或者接口的定义,包含了类的元数据(如常量池、访问标志、类...
class文件是Java编译后的字节码文件,是Java虚拟机(JVM)能够理解和执行的指令...理解class文件结构,可以帮助开发者更好地编写、调试和优化Java程序,同时,这也有助于理解JVM的工作原理和Java虚拟机如何处理字节码。
类装载器负责将.class文件加载到JVM中,并且还负责验证被导入类的正确性、为类变量分配内存并初始化、帮助解析符号引用等。这些操作遵循以下顺序: 1. **装载**:查找并装载类型的二进制数据。 2. **连接**:包含...
总结起来,"JVM之用Java解析class文件"这一主题涵盖了从class文件的结构到JVM加载机制的多个层面。通过学习这一领域,开发者可以更好地理解Java程序的生命周期,提高问题诊断能力,并能利用字节码技术实现高级编程...
第一章:class文件结构.mmap
总的来说,使用C#解析Java的class文件是一项挑战性的任务,它需要对Java字节码格式有深入理解,并熟练掌握C#的IO和数据结构处理。通过这样的实践,开发者不仅可以提升自己的跨语言编程技能,还能增进对Java字节码和...
当Java源代码被编译成字节码(.class文件)后,这些字节码文件可以被部署到任何安装了兼容JVM的平台上执行。需要注意的是,尽管Java语言本身具有良好的跨平台性,但JVM本身并不是跨平台的——不同操作系统上的JVM...