Java虚拟机规范(Java SE 8版)

更多详情

内容简介: 本书由Oracle官方发布,Java虚拟机技术创建人撰写,国内资深Java技术专家翻译。书中基于最新Java SE 8,完整且准确地阐述Java虚拟机规范,是深度了解Java虚拟机和Java语言实现细节的必读之作。
本书共分7章。第1章从宏观的角度介绍了Java虚拟机与Java的关系及发展历程;第2章概述Java虚拟机的整体架构,包括class文件格式、数据类型、原始类型、引用类型、运行时数据区、栈帧、浮点算法、异常等,这对理解本书后面的内容有重要帮助;第3章详述如何将Java语言编写的程序转换为Java虚拟机指令集,涉及常量、局部变量、控制结构、算术运算、参数接收、方法调用、数组、操作数栈、异常处理、同步与注解等;第4章深入分析用来表示编译后的类和接口的class文件格式;第5章定义Java虚拟机启动以及类与接口的加载、链接和初始化过程;第6章阐释并列举Java虚拟机指令集;第7章提供一张以操作码值为索引的Java虚拟机操作码助记符表。

目录: 译者序
前 言
第1章 引言1
1.1 简史1
1.2 Java虚拟机2
1.3 各章节摘要2
1.4 说明3
1.5 反馈3
第2章 Java虚拟机结构4
2.1 class文件格式4
2.2 数据类型5
2.3 原始类型与值5
2.3.1 整数类型与整型值6
2.3.2 浮点类型、取值集合及浮点值6
2.3.3 returnAddress类型和值8
2.3.4 boolean类型8
2.4 引用类型与值9
2.5 运行时数据区9
2.5.1 pc寄存器9
2.5.2 Java虚拟机栈10
2.5.3 Java堆10
2.5.4 方法区11
2.5.5 运行时常量池11
2.5.6 本地方法栈12
2.6 栈帧12
2.6.1 局部变量表13
2.6.2 操作数栈14
2.6.3 动态链接14
2.6.4 方法调用正常完成15
2.6.5 方法调用异常完成15
2.7 对象的表示15
2.8 浮点算法15
2.8.1 Java虚拟机和IEEE 754中的浮点算法15
2.8.2 浮点模式16
2.8.3 数值集合转换17
2.9 特殊方法18
2.10 异常19
2.11 字节码指令集简介20
2.11.1 数据类型与Java虚拟机21
2.11.2 加载和存储指令23
2.11.3 算术指令24
2.11.4 类型转换指令25
2.11.5 对象的创建与操作27
2.11.6 操作数栈管理指令27
2.11.7 控制转移指令27
2.11.8 方法调用和返回指令28
2.11.9 抛出异常28
2.11.10 同步28
2.12 类库29
2.13 公有设计、私有实现30
第3章 Java虚拟机编译器31
3.1 示例的格式说明31
3.2 常量、局部变量和控制结构的使用32
3.3 算术运算36
3.4 访问运行时常量池36
3.5 与控制结构有关的更多示例37
3.6 接收参数40
3.7 方法调用41
3.8 使用类实例43
3.9 数组44
3.10 编译switch语句46
3.11 使用操作数栈48
3.12 抛出异常和处理异常48
3.13 编译finally语句块51
3.14 同步54
3.15 注解55
第4章 class文件格式56
4.1 ClassFile结构57
4.2 各种名称的内部表示形式61
4.2.1 类和接口的二进制名称61
4.2.2 非限定名61
4.3 描述符62
4.3.1 语法符号62
4.3.2 字段描述符62
4.3.3 方法描述符63
4.4 常量池64
4.4.1 CONSTANT_Class_info结构65
4.4.2 CONSTANT_Fieldref_info、CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info结构66
4.4.3 CONSTANT_String_info结构67
4.4.4 CONSTANT_Integer_info和CONSTANT_Float_info结构67
4.4.5 CONSTANT_Long_info和CONSTANT_Double_info结构68
4.4.6 CONSTANT_NameAnd-Type_info结构69
4.4.7 CONSTANT_Utf8_info结构70
4.4.8 CONSTANT_MethodHandle_info结构72
4.4.9 CONSTANT_MethodType_info结构73
4.4.10 CONSTANT_Invoke-Dynamic_info结构74
4.5 字段74
4.6 方法76
4.7 属性78
4.7.1 自定义和命名新的属性82
4.7.2 ConstantValue属性82
4.7.3 Code属性83
4.7.4 StackMapTable属性86
4.7.5 Exceptions属性92
4.7.6 InnerClasses属性93
4.7.7 EnclosingMethod属性95
4.7.8 Synthetic属性96
4.7.9 Signature属性96
4.7.10 SourceFile属性100
4.7.11 SourceDebugExtension属性101
4.7.12 LineNumberTable属性102
4.7.13 LocalVariableTable属性103
4.7.14 LocalVariableTypeTable属性104
4.7.15 Deprecated属性106
4.7.16 RuntimeVisibleAnnota-tions属性106
4.7.17 RuntimeInvisible-Annotations属性110
4.7.18 RuntimeVisibleParameterAnnotations属性111
4.7.19 RuntimeInvisiblePara-meterAnnotations属性112
4.7.20 RuntimeVisibleTypeAnnotations属性114
4.7.21 RuntimeInvisibleType-Annotations属性124
4.7.22 AnnotationDefault属性125
4.7.23 BootstrapMethods属性126
4.7.24 MethodParameters属性127
4.8 格式检查129
4.9 Java虚拟机代码约束129
4.9.1 静态约束130
4.9.2 结构化约束132
4.10 class文件校验135
4.10.1 类型检查验证136
4.10.2 类型推导验证200
4.11 Java虚拟机限制206
第5章 加载、链接与初始化208
5.1 运行时常量池208
5.2 虚拟机启动210
5.3 创建和加载211
5.3.1 使用引导类加载器来加载类型212
5.3.2 使用用户自定义类加载器来加载类型212
5.3.3 创建数组类213
5.3.4 加载限制214
5.3.5 从class文件表示得到类214
5.4 链接215
5.4.1 验证216
5.4.2 准备216
5.4.3 解析217
5.4.4 访问控制225
5.4.5 方法覆盖225
5.5 初始化226
5.6 绑定本地方法实现228
5.7 Java虚拟机退出228
第6章 Java虚拟机指令集229
6.1 设定:“必须”的含义229
6.2 保留操作码229
6.3 虚拟机错误230
6.4 指令描述格式230
6.5 指令集描述232
第7章 操作码助记符320
附录A Limited License Grant327

译者序: 译者序
Java从诞生到现在历经20多年,如今已成为一门应用场合非常广泛的编程语言。而在它逐步发展的过程中,还有另一件事物也在不断发生变化,这就是Java虚拟机。
与某些语言相比,Java的特色之一就是通常需要把编译好的class文件放在虚拟机中执行,而不是直接放在硬件上执行。这种在硬件和二进制文件中加入虚拟机层的做法,自然有其优势与局限性,然而纵观Java语言与Java虚拟机的发展脉络就可看出,各种Java虚拟机的实现者依然在以他们自己的方式不断地优化虚拟机。
虚拟机的具体实现可以有差别,但它们都遵循一套抽象的规则,这就是Java虚拟机规范。这份规范不仅可以使Java虚拟机的实现变得更加协调,而且还阐明了Java虚拟机与Java语言之间的契合点,令实现者可以在保持程序语义不变的前提下获得充分的发挥空间。
从J2SE 5.0开始,Java有了较大改变,加入了泛型、枚举、变长参数、多异常catch语句等特性,到了Java SE 8,更是引入了与lambda表达式相关的许多新功能,使Java语言的写法变得更为灵活。与此同时,Java虚拟机也在针对这些特性而调整。无论读者是否从事虚拟机开发,都可以从研读规范的过程中更为深入地体会这些特性。大家还可以参考Bill Venners所著的《Inside the Java 2 Virtual Machine》(《深入Java虚拟机(原书第2版)》),以了解Java虚拟机的原理及指令细节。
尽管Java虚拟机通常与Java语言配套使用,但除了Java语言之外,用Clojure、Scala等语言所写的程序也可以运行在Java虚拟机上。此外,还可以用Java语言实现出Python、Ruby等语言的解释器,从而将其放在Java虚拟机中执行。这些用法都表明:虚拟机规范不但对学习Java有帮助,而且还能促使我们以全新的手法来运用其他常见的语言。从某种意义上来看,Java虚拟机有其独特的地位,而且还是程序设计领域中的一种思维方式。
翻译本书的过程中,译者参考了由周志明、薛笛、吴璞渊、冶秀刚所翻译的《Java虚拟机规范(Java SE 7版)》,并保留了上一版的部分译者注,在此谨对四位译者深表感谢。同时感谢机械工业出版社华章公司诸位编辑与工作人员的帮助。
本书的风格和术语尽量与上一版相符,有时会酌情稍作调整。欢迎大家发邮件至eastarstormlee@gmail.com,或访问github.com/jeffreybaoshenlee/zh-translation-errata-jvmspec8/issues,给我以批评和指正。该网址还列有《中英文词汇对照表》,以供参考。
爱飞翔

前言: 本书涵盖了自2011年发布Java SE 7版之后所发生的全部变化。此外,为了与常见的Java虚拟机实现相匹配,本书还添加了大量修订及说明。
本版与前面各版一样,仅仅描述了抽象的Java虚拟机,而在实现具体的Java虚拟机时,本书指出了设计规划。Java虚拟机的实现必须体现出本书中的内容,但仅在确有必要时才应该受制于这些规范。
对于Java SE 8来说,Java编程语言里的一些重要变化在这本Java虚拟机规范中都有相应的体现。为了尽量保持二进制兼容性,我们应该直接在Java虚拟机里指定带有默认实现代码的default方法,而不应该依赖于编译器,因为那样做将无法在不同厂商、不同版本的产品之间移植,此外,那种做法也不可能适用于已有的class文件。在设计JSR 335,也就是《Lambda Expressions for the Java Programming Language》(Java编程语言的lambda表达式)时,Oracle公司的Dan Smith向虚拟机实现者咨询了将default方法集成到常量池和方法结构、方法与接口方法解析算法,以及字节码指令集中的最佳方式。JSR 335也允许在class文件级别的接口里出现private方法与static方法,而这些方法也同接口方法解析算法紧密地结合起来了。
Java SE 8的特点之一是:Java SE平台的程序库也伴随着Java虚拟机一起进化。有个小例子可以很好地说明这一特点:在运行程序的时候,Java SE 8可以获取方法的参数名,虚拟机会把这些名字存放在class文件结构中,而与此同时,java.lang.reflect.Parameter里也有个标准的API能够查询这些名字。另外,我们也可以通过class文件结构中一项有趣的统计数据来说明这个特点:本规范的第1版中定义了6个属性,其中有3个属性对Java虚拟机至关重要,而Java SE 8版的规范则定义了23个属性,其中只有5个属性对Java虚拟机很重要。换句话说,在新版规范中,属性主要是为了支持程序库而设计的,其次才是为了支持Java虚拟机本身。为了帮助读者理解class文件结构,本规范会更为清晰地描述出每项属性的角色及其使用限制。
在Oracle公司的Java Platform团队里,有多位同事都对这份规范提供了大力支持,他们包括:Mandy Chung、Joe Darcy、Joel Franck、Staffan Friberg、Yuri Gaevsky、Jon Gibbons、Jeannette Hung、Eric McCorkle、Matherey Nunez、Mark Reinhold、John Rose、Georges Saab、Steve Sides、Bernard Traversat、Michel Trudeau和Mikael Vidstedt。尤其感谢Dan Heidinga (IBM)、Karen Kinnear、Keith McGuigan及Harold Seigel,他们对常见的Java虚拟机实现中的兼容性及安全性贡献良多。
Alex Buckley
于加利福尼亚州圣克拉拉