`
Rolandz
  • 浏览: 6902 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java类文件的基本结构

阅读更多
欢迎来到“Under The Hood”第二期。上期我们讨论了抽象计算机JVM。如果你对JVM还很陌生,你可以去看看上期的文章。本期,我们稍稍窥探一下Java类文件的基本结构。

为旅行而生

Java类文件(.class文件)是一个为已编译Java程序仔细定义的格式。Java源代码被编译成能够被任何JVM加载和执行的类文件。在被JVM加载之前,类文件可能是由网络传输而来。

类文件是独立于底层平台的,所以适用于更多的地方。它们由简洁的JVM字节码组成,这样就能轻装上阵。类文件常常被压缩,以极快的速度通过网络,到达世界各地的JVM。

类文件里有什么?

Java类文件包含JVM需要知道的关于一个Java类或接口的一切。按照它们的出现次序,主要的部分有:魔法数(magic),版本号(version),常量池(constant pool),访问标示符区(access flags),当前类区(this class),超类区(super class),父接口区(interfaces),字段区(fields),方法列表区(methods),属性区(attributes)。

保存在类文件中的信息经常在长度上有变化,所以信息的实际长度在被加载之前不能被预测。例如,在方法区里的方法数目,类与类之间是不相同的,这取决于源代码中定义的方法个数。类文件中,这些信息的实际大小或长度,被安排在信息内容之前。这样,当类文件被JVM加载时,可变信息的长度首先被读取。一旦JVM知道信息的大小,它就能正确的读取实际的信息内容。

类文件中,不同的相邻信息之间通常没有空白或填充字符;一切都以字节(byte)边界对齐。这使得类文件很小,适合网络传输。

为了让JVM在加载类文件时,知道需要什么信息以及从哪里可以取得所需信息,类文件的各个组成部分的次序是严格定义的。例如,每个JVM都知道类文件的前8个字节由魔法数和版本号组成,常量池从第9个字节开始,访问标示符区紧跟在常量池后面。但是,因为常量池的长度是可变的,在读取完常量池之前,JVM是不知道访问标示符区具体从什么地方开始。一旦读取完常量池,JVM就知道接下来的2个字节就是访问标示符区。

魔法数(Magic)和版本号(Version)

每个类文件的开始4个字节都是0xCAFEBABE。这个神奇的数字让Java类文件更容易识别,因为类文件以外的文件几乎不可能也以这四个相同的字节开头。之所以称之为魔法数,是因为它可以被文件格式设计者们从帽子里拉出来(??)。对它仅有的要求是,不能被现实已有的文件格式占用。根据最初Java团队主要成员之一的Patrick Naughton所说,远在“Java”被当作Java语言的名称之前,这个神奇的数字就已经被选好了。我们当时在寻找一个有趣,独特并且很容易记住的数字。0xCAFEBABE作为漂亮的Peet’s Coffee的咖啡师的代称,能预示未来Java语言的名字,这完全是一个巧合。

类文件接下来的4个字节包含了大版本号(major version)和小版本号(minor version)。这些数字标识了特定类文件使用的类文件格式,让JVM可以验证类文件是否可以被载入。每个JVM都有一个它能载入的最大版本号,拒绝加载大于最大版本号的类文件。

常量池(Constant Pool)

类文件在常量池中保存与类或接口关联的常量。常量池中能看到的部分常量是字符串字面值(literal strings),final变量的值(final variable values),类名,接口名,变量名和变量类型,方法名和方法签名(method names and signatures)。方法签名由方法返回值类型(return type)和一组参数类型(argument types)组成。

常量池被组织成一个元素长度可变的数组。每个常量占据数组中的一个元素。在整个类文件中,常量通过指示它们在数组中位置的整型索引来引用。第一个常量的索引值是1,第二个是2,以此类推。常量池数组的元素个数写在常量池的前面,所以在加载类文件时,JVM知道它需要加载多少常量。

常量池中每个元素以指明自己类型的单字节标签(tag)开始。一旦JVM看到这个标签,就能知道接下来会遇到什么类型的常量。例如,如果看到一个表示字符串的标签,JVM会认为接下来2个字节就是字符串的长度,然后就是“长度”个字节组成的字符串。

在本文剩下的部分,我有时会用constant_pool[n]表示常量池数组的第n个元素。从常量池组织的像个数组来说,这是有道理的;但是请记住,这些元素具有不同的大小和类型,并且第一个元素的索引是1。

访问标识符区(Access Flags)

常量池之后的2个字节就是访问标示符,它表明该文件定义的是类还是接口;该类或接口是公开的(public)还是抽象的(abstract);如果是类,该类是不是final的。

当前类区(This class)

接下来2个字节是当前类区,它是常量池数组的索引。被当前类引用的常量constant_pool[this_class],包含两部分:单字节标签(tag)和双字节名称索引(name index)。标签等于CONSTANT_Class,一个表示本元素中包含类或接口信息的值。constant_pool[name_index]是一个包含类或接口名的字符串常量。

当前类部分稍稍揭示了常量池是怎么被使用的。当前类区本身只是一个常量池的索引。当JVM查找constant_pool[this_class]时,它找到一个用标签表明自己是一个CONSTANT_Class得元素。JVM知道CONSTANT_Class元素在标签(tag)之后,总是有一个叫名称索引(name index)的常量池双字节索引。然后它查找constant_pool[name_index],得到包含类或接口名的字符串。

超类区(Super class)

当前类区之后是超类区,也是2个字节的常量池索引。constant_pool[super_class]是CONSTANT_Class元素,它指向当前类所直接继承的超类名。

接口区(Interfaces)

接口区开头的2个字节,表示文件所定义的类(或接口)实现的接口数目。紧接着是一个数组,它包含了类所实现的每一个接口在常量池中的索引。
每个接口都是常量池中的CONSTANT_Class元素,它指向接口名。

字段区(Fields)

字段部分,以表示该类或接口包含的字段数的2个字节开始。字段是一个实例变量,或者是类或接口的类变量。接下来是一个以可变长结构为元素的数组,一个结构一个字段。每个结构都包含一个字段的相关信息,如字段名,字段类型,如果是final变量,还包括字段值。部分信息在结构当中,另一部分在常量池中由结构所指向的位置。

这部分仅有的字段,都是由定义在该类文件中的类或接口声明的变量;继承自超类或接口的字段不在此列。

方法区(Methods)

方法部分,以表示类或接口中方法数目的2字节开始。这个数目,只包含当前类显式定义的方法,不包括继承自超类的方法。数目之后是方法本身。

表示每个方法的结构包含方法相关的几条信息,包括方法描述符(method descriptor,包括返回值类型和参数列表),方法本地变量需要的栈字(stack words)数,方法操作数栈(operand stack)需要的最大栈字数,方法捕获的异常表,字节码序列和行号表。

属性区(Attributes)

排在最后的是属性区,它提供定义在类文件中的特定类或接口的一般信息。属性区以2字节的属性数目开始,然后是属性本身。比如一个表示源码属性的属性:它表示当前类被编译而来的源文件名。JVM会悄悄地忽略任何它们识别不了的属性。

本文译自:The Java class file lifestyle

原创文章,转载请注明: 转载自LetsCoding.cn
本文链接地址: Java类文件的基本结构
0
3
分享到:
评论

相关推荐

    Java类文件的基本结构_.docx

    以下是对Java类文件基本结构的详细解析: 1. 魔法数(Magic Number)和版本号(Version) 类文件的起始4字节是固定的魔数0xCAFEBABE,用于识别文件是否为Java类文件。紧接着的4字节是大版本号和小版本号,它们标识...

    java所有类结构(pdf文件)

    这份"java所有类结构"的PDF文档提供了全面的Java类层次结构,对于深入学习Java编程至关重要。以下将详细介绍PDF文档中可能涉及的一些重要Java类和概念。 首先,`java.awt.font.Font`类是处理字体的基础,它允许程序...

    JavaClass文件的结构分析及其校验.pdf

    Java文件校验器通过四次独立扫描完成校验工作: 1. **Class文件的结构检查**:在类装载时执行,主要检查Class文件的内部结构是否符合标准,以保证文件的安全编译。 2. **类型数据的语义检查**:在连接过程中进行,...

    JAVA基本5种数据结构的实现。

    虽然这里没有明确的堆实现文件,但Java提供了`java.util.PriorityQueue`来实现堆数据结构。 在实际编程中,这些数据结构的选择取决于特定的需求,例如快速访问、高效的插入和删除等。理解并熟练使用这些数据结构...

    JAVA版数据结构.pdf

    文中提到了数据结构(Data Structures)和Java语言的结合,这表明文档可能涉及数据结构在Java中的实现方式,包括基本的结构如数组、链表、栈、队列、树和图等,以及它们的特性、操作方法和应用场景。 2. Java中的...

    java遍历文件目录生成树结构txt文件

    在Java编程中,遍历文件目录并生成树结构的文本文件是一个常见的任务,尤其是在处理大量文件数据时。这个任务可以通过使用Java的`java.io.File`类及其相关API来实现。`Dir.class`和`Dir.java`是这次操作的核心文件,...

    JAXB 利用xsd文件生成java类

    在Java开发中,JAXB提供了一种方便的方式,允许开发者通过XML Schema (XSD) 文件来生成对应的Java类,从而简化XML处理的工作流程。 1. **XML Schema (XSD) 文件**: - XML Schema是一种W3C标准,用于定义XML文档的...

    MySQL表自动生成Java实体类

    7. **运行脚本/工具**: 执行这个自动化过程,生成的Java实体类文件将被放置在指定的输出路径下,可以直接引入到Java项目中使用。 通过这样的自动化过程,开发者可以从繁琐的手动编码工作中解脱出来,专注于业务逻辑...

    JAVA_API1.6文档(中文)

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    数据结构(java版本)

    《数据结构(Java版本)》这本书正是为此目的而编写,旨在将理论与实际编程相结合,通过Java语言来实现各种经典的数据结构。 首先,书中的基础部分会介绍数据结构的基本概念,如数组、链表、栈和队列。数组是最基本...

    java_树形结构文档

    总之,"java_树形结构文档"可能涵盖了上述内容,包括但不限于树的基本概念、Java中实现树的类结构、树的遍历方法、特定树结构如二叉树和红黑树的特性和应用。通过学习这个文档,开发者将能够更好地理解和利用树形...

    JAVA基本类源代码

    这个压缩包“基本类源代码”很可能包含了Java语言中的一些基础类的源文件,例如`Object`类、`String`类、`Integer`类、`ArrayList`类等。这些类在Java开发中非常常见,深入理解它们的源代码对于提升编程技能和优化...

    数据结构JAVA实现

    再来说说队列,它是另一种基本的数据结构,遵循先进先出(FIFO)的原则。在Java中,队列可以通过`java.util.Queue`接口实现,常见的实现类有`LinkedList`和`ArrayDeque`。队列的主要操作包括入队(enqueue,将元素...

    java学习课件,包含了Java语言的基本结构,数据等,很详细

    首先,我们要了解Java语言的基本结构。Java程序的结构通常包括类(class)、方法(method)和变量(variable)。类是Java中的基本构造块,用于封装数据和行为。方法是执行特定任务的代码块,而变量则用来存储数据。...

    Java API文档.docx

    Java API文档包含了Java类库中的大量类和接口,例如`java.lang`包下的基本类如`String`、`Integer`,以及`java.util`包中的集合类如`ArrayList`、`HashMap`。接口如`Comparable`和`Iterable`定义了通用的行为规范,...

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

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

    邓俊辉版java 数据结构源码

    队列是先进先出(FIFO)的数据结构,Java的LinkedList类可以方便地实现队列功能,或者使用ArrayDeque类的双端队列特性。 树是一种非线性的数据结构,二叉树是其中最简单的一种,每个节点最多有两个子节点。AVL树是...

    树形结构设计总结java demo

    本篇文章将深入探讨“树形结构设计”在Java环境下的实现,并结合给出的链接资源——一篇在CSDN博客上的文章(虽然无法直接访问,但我们可以根据描述推测其内容),以及名为“tms”的压缩包文件,来解析相关知识点。...

    java IO 类层次图

    ### Java IO 类层次结构解析 #### 一、概述 Java IO(Input/Output)系统是Java平台中的一个重要组成部分,用于处理程序与外部设备之间的数据交换。Java IO系统提供了丰富的类来支持不同类型的输入输出操作,包括...

Global site tag (gtag.js) - Google Analytics