这篇文章针对虚拟机的抽象描述,并不针对一个特定的Java虚拟机实现。
为了实现Java虚拟机,你仅仅需要能够读取class文件格式,并且执行里面的操作。哪些限制实现者创造力的具体细节并不是Java虚拟机规范的一部分。例如,运行时数据区域的内存结构,垃圾回收运用的算法,Java虚拟机指令的内部优化(例如转换成机器码)等这些实现细节都留给实现者去自由决断。
虚拟机规范中所有的Unicode码都是采用
The Unicode Standard, Version 6.0.0,可以在 http://www.unicode.org/.获得。
2.1 类文件格式
虚拟机中执行的编译后的代码是一种与硬件和操作系统无关的二进制格式,通常情况下(但不是必须)存储在文件中,即大家熟知的class文件。这种class文件格式精确的定义了类和接口的表示,比如包含用于确保平台特有的对象文件的字节顺序。
第四章 会再次详细讨论类文件的格式
2.2 数据类型
类似于Java编程语言,Java虚拟机也是在两种数据类型上进行操作:基本数据类型和引用数据类型。相应的存在两种数值可以被存储到变量中、作为参数传递、作为方法返回值、被操作:基本数值和引用数值。
Java虚拟机期望所有的类型检测都在运行前被执行,通常是靠编译器,而不是靠虚拟机自己来做。基本类型不需要被标记,或者能够被检测出以用来在运行时确定其类型,也不需要和引用类型的值区分开来。相反,Java虚拟机的指令集用操作特定类型的指令来区分被操作数值的类型。例如:iadd, ladd, fadd, 和 dadd都是用来操作两个数,并算出一个数值的指令集,但是每一个都相应的专门针对它操作的类型 int,long,float,double。可以参照2.11.1查阅Java虚拟机支持的指令集的概述。
Java虚拟机明确的包含了对对象的支持。一个对象是一个动态分配的类实例或者是一个数组。一个对象的引用被认为是Java虚拟机的引用类型。引用类型的值可以想成一个对象的指针。同一个对象可以有多个引用。对象通常利用引用类型来操作、传递、测试。
2.3 基本类型和值
Java虚拟机包支持的数据类型有:数字类型、boolean类型(2.3.4)、returnAddress类型(2.3.3)。
数字类型又分为整数类型(2.3.1)和浮点数类型(2.3.2)。
整数类型有:
- byte :8位的有符号整数,默认值是0
- short:16位的有符号整数,默认值是0
- int :32位的有符号整数,默认值是0
- char :16位的无符号整数,采用UTF-16来编码,默认值是'\u0000'
- long :64位的有符号整数,默认值是0
浮点数类型有:
- float :值是浮点数集的元素,如果虚拟机支持也可以是浮点数扩展指数集,默认值是正0
- double:值是双精度数集的元素,如果虚拟机支持也可以是双精度数扩展指数集,默认值是正0
boolean类型的值表示true和false,默认值是false。
returnAddress类型的值是Java虚拟机指令集的操作码的指针,在所有的基本数据类型中,只有returnAddress类型在Java编程语言中没有直接对应的类型。
2.3.1 整数类型和值
对于Java虚拟机整数类型的值有:
- byte :范围是[-128,127]
- short :范围是[-32768,32767]
- int :范围是[-2147483648,2147483647]
- long :范围是[-9223372036854775808,9223372036854775807]
- char :范围是[0,65535]
2.3.2 浮点类型和值
浮点数类型包含float和double,概念上等价于32位的单精度数和64位的双精度数,采用IEEE 754标准格式。
IEEE 754标准不仅包含正负有符号数,还有正0和负0,正无穷和负无穷,以及一个特殊的NaN值。NaN用来代表一个非法操作的结果,例如0除0的结果。
2.3.3 returnAddress类型和值
returnAddress类型被Java虚拟机的jsr, ret, 和 jsr_w指令利用。它的值表示Java虚拟机指令操作码的地质。不像数值基本类型,returnAddress类型没有对应的Java语言类型。它的值也不能被运行程序修改。
2.3.4 boolean类型
虽然Java虚拟机定义了boolean类型,但是它对boolean类型只提供了非常有限的支持。并没有专门操作boolean类型的指令。Java语言中操作boolean类型的表达式编译后利用的是Java虚拟机的int类型。
Java虚拟机并不直接支持boolean数组,newarray 指令能够创建一个新的boolean数组,但是虚拟机对boolean数组的访问和修改用的是字节数组的指令baload和bastore。
Java虚拟机用1表示true,0表示false来编码boolean数组的内容,如果Java编程语言的boolean类型值被编译映射成虚拟机的int类型,编译器也需要用相同的编码格式。
2.4 引用类型
引用类型分为三类:类、数组、接口。相应的它们的值对应着动态生成的类实例、数组和实现了接口的类实例或数组。
数组类型由一维的组件类型组成,数组类型的组件类型自己也可以是数组。如果数组的组件类型也是数组,则组件类型的组件类型最终必然不是一个数组,称之为元素类型。元素类型只能是类类型、接口类型、或基本类型。
引用类型的值也可以是一个特殊的null,一个不指向任何对象的引用,即null引用。null引用没有运行时类型,但是可以转换成任意类型。引用类型的默认值就是null。
虚拟机规范并不强制要求使用一个具体的值编码为null。