1 JVM的“平台无关性”
Java具有平台无关性,即任何操作系统都能运行Java代码。
之所以能实现这一点,是因为Java运行在虚拟机之上,不同的操作系统都拥有各自的Java虚拟机,因此Java能实现"一次编写,处处运行"。
而JVM不仅具有平台无关性,还具有语言无关性:
- 平台无关性是指不同操作系统都有各自的JVM
- 语言无关性是指Java虚拟机能运行除Java以外的代码!
但JVM对能运行的语言是有严格要求的。首先来了解下Java代码的运行过程:
Java源代码首先需要使用Javac编译器编译成class文件,然后启动JVM执行class文件,从而程序开始运行。
即JVM只认识class文件,它并不管何种语言生成了class文件,只要class文件符合JVM的规范就能运行。
因此目前已经有Scala、JRuby、Jython等语言能够在JVM上运行。它们有各自的语法规则,不过它们的编译器都能将各自的源码编译成符合JVM规范的class文件,从而能够借助JVM运行它们。
Class文件是JVM的输入, Java虚拟机规范中定义了Class文件的结构。Class文件是JVM实现平台无关、技术无关的基础。
2 纵观Class文件结构
class文件包含Java程序执行的字节码,数据严格按照格式紧凑排列在class文件中的二进制流,中间无任何分隔符。
文件开头有一个0xcafebabe(16进制)特殊的一个标志。
- 下图展示为16进制
class文件是一组以8字节为单位的二进制字节流,对于占用空间大于8字节的数据项,按照高位在前的方式分割成多个8字节进行存储。
它的内容具有严格的规范,文件中没有任何分隔符,全是连续的0/1。
class文件中的所有内容被分为两种类型:
- 无符号数
基本的数据类型,以u1、u2、u4、u8,分别代表1字节、2字节、4字节、8字节的无符号数 - 表
class文件中所有数据(即无符号数)要么单独存在,要么由多个无符号数组成二维表.即class文件中的数据要么是单个值,要么是二维表.通常以_info 结尾
文件格式
javap工具生成非正式的"虚拟机汇编语言” ,格式如下:
<index> <opcode> [<operand1> [<operand2> ...]][<comment>]
<index>
是指令操作码在数组中的下标,该数组以字节形式来存储当前方法的Java虚拟机代码;也可以是相对于方法起始处的字节偏移量<opcode>
是指令的助记码< operand>
是操作数<comment>
是行尾的注释
ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; }
实践
- Demo1.java
Demo1.txt
版本号规则: JDK5,6,7,8
分别对应49,50,51,52
2.1 魔数(Magic Number)
class文件的头4个字节称为魔数,唯一作用是确定这个文件是否为一个能被JVM接受的Class文件.
作用就相当于文件后缀名,只不过后缀名容易被修改,不安全.
是用16进制表示的"CAFEBABE".
2.2 版本信息
紧接着魔数的4个字节是版本号.它表示本class中使用的是哪个版本的JDK.
在高版本的JVM上能够运行低版本的class文件,但在低版本的JVM上无法运行高版本的class文件.