`
不平凡的人
  • 浏览: 35194 次
  • 性别: Icon_minigender_1
  • 来自: 嘉峪关
社区版块
存档分类
最新评论

类文件结构

 
阅读更多

本文从以下方面描述类文件结构:

 

(一)class文件的结构

一、魔数与class文件版本

二、常量池

三、访问标志

四、类索引、父类索引、接口索引集合

五、字段表集合

六、方法表集合

七、属性表集合

 

(一)class文件的结构

 

1、概述

            class文件是以8位字节为基本单位二进制流,各个结构严格按照顺序排列起来,中间没有任何分割符。  当遇到要占用8位字节以上的空间数据时,则会按照高位在前的方式分割成若干个字节进行存储。

 

2、class文件中的数据类型

 Java虚拟机规范规定,Class文件的格式采用一种类似C语言的结构体的伪结构存储。

 有两种数据类型:

 (1)无符号数

 (2)表

 

2.1、无符号数

         属于基本数据类型,以u1,u2,u4,u8分别表示1字节,2字节,4字节,8字节的无符号数;

         无符号数用来描述:数字,索引引用,数量值,或者按照UTF-8编码的字符串值。

 

2.2、表

         表是有多个无符号数,或者其他表作为数据项构成的复合数据类型,所有表习惯以“_info”结尾;

 

2.3、图示class文件格式


 

 一、魔数与class文件版本

 

1、概述

             class文件的开始4字节表示为魔数(Magic Number)。开始四字节值为0xCAFEBABE。

2、作用

            用于确定该文件是否是一个能被虚拟机加载的Class文件。

 3、次版本、主版本

            紧随魔术之后的u2为次版本(minor_version),之后的u2两个字节为主版本(major_version)



 

4、class文件的版本号



 

二、常量池

 

 1、概述

              在次版本、主版本之后的数据项为常量池,常量池与class文件中其他项目关联最为密切,也是占用class文件最大的数据项之一,也是class文件中第一个出现表结构的数据。

 

2、常量池池容量计数值(constant_pool_count)

      常量池的入口放置一个u2类型的数据,代表常量池容量计数值(constant_pool_count)。池容量计数值是从1开始的,0项有特殊意义(0项,为了满足某些指向常量池的索引值的数据在特定的情况下需要表达“不引用任何一个常量池项目”)。

 

2.1、注意             

        Class文件中只有常量池是从1开始计数,其他集合类型,诸如:接口索引集合、字段表集合、方法表集合、等计数从0开始。

 

3、常量池存放的常量类型

(1)字面量(Literal)

(2)符号引用(Symbolic References)

 

3.1、字面量

        类似于java中的常量,如:文本字符串、被声明为final的常量值。

 

3.2、符号引用

         属于编译原理方面的概念,包括如下3类常量:

       (1)类和接口的全限定名(Full Qualified Name)

       (2)字段名称和描述符

       (3)方法名称和描述符

 

3.2.1 全限定名、简单名称、描述符

(1)全限定名:包名与类名组成的字符串

(2)简单名称:没有类型和参数修饰符的方法或字段名称

 

(3)描述符:

         ① 用于描述:字段的数据类型,方法的参数列表(包括参数类型,数量,顺序)以及方法返回值;

         ②描述符规则:8个基本数据类型以及无返回值的void都用一个大写字母表示,见下图。对于对象类型来说用字符大写L加对象的全限定名表示,如:Ljava/lang/String;

         ③数组表示:一维数组如:int[]表示为[I,二维数组java.lang.String[][]表示为[[Ljava.lang.String

         ④描述符用于描述方法参数时,按照先参数列表,后返回值的顺序描述。如方法void fun(),表示为

()V,java.lang.String toString(),表示为 ()Ljava.lang.String

   

3.2.2、描述符表示含义图



 

 4、常量池中的项目类型

       常量池的每一项常量都是一张表,共有11项目数据各不相同的表结构数据,11中表结构数据都有一个共同点,开始位置都是u1类型的标志位(tag,取值1-12,缺少标志2数据类型),tag标志位表示当前的常量属于那种常量类型,11中常量类型的含义见下图:


 

 4.1、11中数据类型结构总表

 

 

 

 三、访问标志(access_flags)

       

1、概述:

      紧随常量池之后的u2类型的数据代表访问标志(access_flags)。

       

2、作用:

      识别类或接口的访问信息,包括,class为类或接口,是否定义为public、是否定义为abstract;如果为类是否声明为final。

 

3、访问表示的含义表



 
4、说明

      access_flag共有32个标志位可以使用,当前只定义了8个,没有用到的标志位都为0。

      例如:用到了 ACC_PUBLIC(0x0001)以及ACC_SUPER(0x0020), 0x0001 | 0x0020 = 0x0021(呈现在字节码中文件的16进制数),所以其他几项标志位都为0。  

   

四、类索引、父类索引、接口索引集合

 

1、概述

            类索引(this_class)和父类索引(super_class)都是一个u2的数据类型,而接口索引集合(interfaces)是一组u2类型的数据集合,class文件通过上述数据类型确定继承关系。这些类型的数据按顺序排列在访问标志(access_flags)之后。

 

1.1、类索引(this_class)

            用于确定类的全限定名。

1.2、父类索引(super_class)

            用于确定这个类的父类的全限定名。java不支持多继承,除了java.lang.Object之外,所有的类都有父类,所以父类索引不为0。

1.3、接口索引集合(interfaces)

            用于描述类实现了那些接口,这些实现的接口(如果类本身是接口,则为多继承extends)将按照implements语句后的接口顺序从左到右排列在接口索引集合中。

 

2、说明

 

(1)类索引(this_class)和父类索引(super_class)引用u2类型的索引值表示,它们指向一个类型为CONSTANTS_Class_info的描述符常量,通过CONSTANTS_Class_info类型中的常量索引值可以找到定义在CONSTANTS_Utf8_info类型的常量中的全限定名字符串。

 

(2)接口索引集合,第一项为一个u2类型的接口计数器(interfaces_count),表示索引表的容量。

 

 五、字段表集合(fields) 

 

1、概述

      字段表(fields_info)用于描述类或接口中的变量。

      字段(fields)包括,类变量和实例变量,不包括方法内部声明的变量。

     

1.1、描述一个字段包括的信息:

       ①字段的作用域(public 、private、protected);

       ②类变量后者是实例变量(static);

       ③是否为常量final;

       ④并发可见性volatile是否强制从内存读写;

       ⑤可否序列化(transient);

       ⑥字段的数据类型(基本数据类型、数组、对象)

 

 1.2、对于字段的修饰符都是boolean值,适合使用标志位来表示,对于字段的数据类型、字段的名字不确定,只能应用常量池中的常量来表示。

 

2、字段表结构

 

 

字段访问标志(access)

 

 3、说明

 (1)紧随访问标志是两项索引值:name_index、description_index。都是对常量池的引用,分别代表着字段的简单名称和方法的描述符。(前面章节已经解释过描述符)。对于description_index之后的attribute_info信息,在后续的章节介绍。

 (2)字段表集合集合中不会列举出从父类中继承来的字段。但可能会出现代码中不存在的字段,比如内部类保持对外部类的访问,会自动添加指向外部类的实例字段。

(3)java中字段无法重载,字段名称不能重名。对于字节码而言,两个字段的描述符(描述字段的数据类型)不一致,字段名称相同是合法的。

 

 六、方法表集合(method_info)

 

1、方法表结构



 方法的访问标志(access_flags)


 

2、特征签名

      java代码中方法的特征签名只包括了方法的名称、参数顺序、参数的类型,而字节码文件中特征签名还包括方法的返回值及受查异常表。

 

3、说明

(1)volatile、transient关键字不能修饰方法,因此访问标志中没有上述两种标志。

(2)java方法中的代码,存放在属性表集合中一个名为“code”的属性里面,后续介绍属性表。

(3)如果父类的方法在子类中没有被重写,方法表集合中不会出现来自父类的方法信息(所见即所得,只针对该类文件中出现的方法进行编译)。同样,可能会出现编译器自动添加方法,典型的为类构造器“<clinit>"和实例构造器"<init>"方法

(4)Java中方法的重载,除了与原方法名称一样,还必须拥有一个与原方法不同的特征签名,返回值不会包括在特征签名之内,java中不能依靠返回值不同对方法重载。

(5)class文件中,两个方法同名,同特征签名,方法的返回值不同,可以共存于一个class文件中。

 

 七、属性表集合

         属性表(attribute_info):class文件中字段表,方法表可以带有自己的属性表集合,用于描述某些场景的专有信息。

 

虚拟机规范定义的属性:



 

 对于上述属性的名称,则需要从常量池中引用一个CONSTANT_Utf8_info类型的常量表示,而属性值的结构则是完全自定义的。

 

7.1 Code属性

      java方法体中的代码经过javac编译之后,最终的字节码指令存储在Code属性内。Code属性出现在方法表的属性集合之中,并不是所有的方法都有该属性,比如说:接口,抽象类中的抽象方法。

 

1、code属性

 

code属性的结构:

 

 (1)attribute_name_index是指向CONSTANT_Utf8_info型的常量的索引,常量值固定为“Code”;

          attribute_length指示了属性值的长度,属性名+属性值=u6字节,所以整个code属性减去6字节为属性值的长度;

 

(2)max_stack:操作数栈(Oprand Stacks)深度的最大值。方法执行的任意时刻,操作数栈都不会超过这个深度。虚拟机运行时需要根据这个值来分配栈帧中操作数栈的深度。

 

(3)max_locals:代表局部变量所需的存储空间。max_locals单位是slot。

         slot是虚拟机为局部变量分配内存所使用的最小单位。1slot为32位。

 

(4)code,code_length:用于存储java源程序编译后生成的字节码指令。

         code_length为u4类型的长度值,理论上最大值可以达到2的32次方-1,虚拟机规范中规定方法不允许超过65535条字节码指令,如果超过了该限制,javac编译器会拒绝编译。

         code属性为class文件中的一个重要的属性,如果把一个java程序中信息一分为二,java代码(code,方法体里的java代码)和元数据(Metadata,包括类、字段、方法及其他信息)两部分。code属性则用于描述代码,所有其他数据项用于描述元数据。

 

(5)exception_info:异常表信息

         异常表中有四个字段:start_pc行到end_pc行(不包含end_pc行),出现了catch_type或其子类型异常,则跳转到handler_pc行继续处理。

         如果,catch_type的值为0,代表任何异常情况都要转向到handler_pc处进行处理。

 

 2、Exceptions属性

       该Exceptions属性是在方法表中与Code属性平级的一项属性。Exceptions属性列出的是可抛出的受检查的异常(编译时期的异常),也就是方法上声明的throws关键字后面列出的异常。

 

3、LineNumberTable属性

      该属性用于描述java源码行号与字节码行号之间的对应关系。该属性并不是运行时的必须属性。

 

4、LocalVariableTable属性

      用于描述栈帧中局部变量表中的变量与java源码中定义变量的关系,运行时非必须的属性。

 

5、SourceFile属性

      描述生成class文件的源码文件的名称。该属性为可选属性。

 

6、ConstantValue属性

      该属性通知虚拟机为静态变量自动赋值。

      对于实例变量赋值是在实例构造器<init>方法中进行的;

      类变量两种方式赋值:

              ①类构造器<client>方法中进行。

              ②使用constantvalue属性来赋值。

     如果final,static同时,修饰一个变量则为常量,并且该常量类型的为基本数据类型或者是字符串类型,就生成ConstantValue属性来进行初始化;如果变量未被final修饰,并且为非基本类型以及字符串类型,则选择在<clinit>方法中初始化。

 

7、innerclass属性

      描述内部类与外部类之间的关联。

 

 

上述内容参考自  周志明 《深入理解虚拟机》一书。。。

  • 大小: 56.3 KB
  • 大小: 30.7 KB
  • 大小: 97.6 KB
  • 大小: 40 KB
  • 大小: 78.7 KB
  • 大小: 136.3 KB
  • 大小: 92.1 KB
  • 大小: 78.3 KB
  • 大小: 23.7 KB
  • 大小: 61.8 KB
  • 大小: 20.5 KB
  • 大小: 86 KB
  • 大小: 51.6 KB
  • 大小: 31.2 KB
分享到:
评论

相关推荐

    class类文件结构.xmind

    Java虚拟机中的class类文件的知识,个人整理大的class类文件结构.xmind,有什么问题及时反馈。

    Class类文件结构图解

    首先,让我们来看一下`class类文件结构.png`这张图片。它可能展示了一个清晰的视觉表示,列出了Class文件的各个组成部分,如魔数(Magic Number)、版本号、常量池(Constant Pool)、访问标志(Access Flags)、...

    类文件结构1

    Java 类文件结构是Java虚拟机(JVM)执行字节码的基础,它的核心部分就是类文件,其中包含了关于类和接口的各种元数据。类文件的结构严格定义,以确保跨平台的兼容性。这里我们将详细探讨类文件结构中的常量池、常量...

    类文件结构示例

    类文件结构示例,在深入浅出JVM博文中进行演示。如果无关,无需下载。

    【Java正来-深入理解JVM】类文件结构

    JVM的指令由一个字节长度、代表着某种特定操作含义的数字(成为操作码)以及跟随其后的零至多个代表此操作所需参数(操作数)而构成。JVM采用面向操作数栈而不是寄存器架构,所以大多只有一个操作码。

    java类文件结构(笔记).docx

    Java 类文件结构是Java虚拟机(JVM)执行的基础,它包含了构成Java程序的所有必要信息。Class文件是一种二进制格式,由8位字节组成,数据紧密排列,没有额外的分隔符,确保高效存储。Class文件由一系列的数据项组成...

    深入理解jvm-2Edition-类文件结构(csdn)————程序.pdf

    《深入理解JVM-2Edition-类文件结构》是一份详细阐述Java虚拟机(JVM)如何处理类文件的文档。类文件是Java程序编译后的二进制表示,其结构直接影响了Java的平台无关性和语言无关性。下面将详细探讨类文件的各个组成...

    16种文件的数据结构

    0001 ani文件数据结构以及分解ani文件的图像的代码. 0002 bmp文件数据结构.txt 0003 FLV文件数据结构以及读取其脚本信息的代码.txt 0004 gif文件数据结构.txt 0005 ico文件数据结构以及制作特大图标的代码.txt ...

    class文件结构浅析

    ### Class文件结构浅析 #### 一、引言 在深入了解Class文件的结构之前,我们需要明确Class文件在Java生态系统中的重要地位。Java程序被编译器编译后生成的`.class`文件,实际上是字节码文件,它们是Java虚拟机...

    MIDI文件结构简介

    ### MIDI文件结构简介 #### 一、MIDI文件概述 MIDI(Musical Instrument Digital Interface,乐器数字接口)文件是一种存储音乐信息的标准格式,广泛应用于电子乐器、音乐制作软件及移动设备等领域。这类文件并不...

    ttf文件结构说明

    解析TTF文件需要对它的结构有充分的了解,以下是TrueType字体文件结构的主要知识点。 首先,TrueType字体文件以一个 Offset Table(偏移表)开始,从字节0开始,它的存在使得字形渲染器可以更容易地遍历各个表。...

    深入理解JVM之Class类文件结构详解

    深入理解JVM之Class类文件结构详解 Java虚拟机(JVM)是一种运行Java字节码的虚拟机器,Class文件是JVM执行Java程序的基础。Class文件结构是JVM的核心组件之一,对于Java开发者来说,理解Class文件结构是非常重要的...

    树形结构之文件结构

    树形结构之文件结构 简单代码,如何打开文件时在界面以树形方式显示子目录和文件

    PDF文件结构查看器

    PDF文件结构查看器是一款专为分析PDF文档设计的工具,它可以帮助用户深入理解PDF文件的内部构造,并进行数据提取。PDF(Portable Document Format)是一种广泛使用的文档格式,它能够跨平台保持一致的显示效果,因此...

    15种文件的数据结构

    在IT领域,了解不同文件的数据结构对于开发、分析和处理这些文件至关重要。下面将详细讨论标题和描述中提及的15种文件的数据结构,并提供一些VB6代码示例。 1. **MID文件数据结构**:MIDI(Musical Instrument ...

    dicom文件——SR类型结构化报告文件样例数据

    这两个文件都是DICOM SR类型的实例,可能分别代表当前状态和先前状态的结构化报告数据。它们包含的信息可能包括患者的病史、检查过程、观察结果、诊断结论等。为了理解这些文件的具体内容,我们需要使用DICOM查看器...

    rar压缩包4.0,文件结构总结

    RAR压缩包4.0文件结构总结 RAR压缩包4.0文件结构主要由以下几部分组成:HEAD_CRC...RAR压缩包4.0文件结构主要由HEAD_CRC、HEAD_TYPE、HEAD_FLAGS、HEAD_SIZE、ADD_SIZE等结构组成,每种块类型都有其特定的结构和属性。

    dbf文件结构说明及实例文件

    DBF文件结构主要由以下几个部分组成: 1. **文件头(Header)**:文件开头的部分,包含关于整个文件的基本信息,如文件创建日期、记录数量、字段数量、字段定义等。文件头通常为32个字节。 2. **字段头(Field ...

Global site tag (gtag.js) - Google Analytics