概述
把编写的程序转换成二进制本地机器码不是唯一的选择了,不同的计算机硬件系统支持不同的二进制本地机器码,有不同的指令集。
无关性的基石
java虚拟机具有平台无关性,原因在于他接收的是class文件保存的字节码,这种字节码是不分操作系统和硬件设施的。
java虚拟机还要实现语言无关性,除了java语言写出来的程序可以转为class文件,其他别的语言写出来的程序通过不同的编译器也可以编译成储存字节码的class文件,就可以使用java虚拟机。
Class类文件的结构
class文件是由以8字节为基础单位的二进制流组成的,其数据类型有无符号数和表;
无符号数是基本的数据类型,用u1,u2,u4,u8来表示1、2、4、8字节的无符号数,可以用来描述数字,参数引用,数量值,以及以utf-8编码构成的字符串值
表是由无符号数和其他表组成的复合数据类型,以_info结尾,整个class文件也是一个表;
当需要描述同一个类型的多个数据的时候,先是表达出有多少个数据,然后后面接着这些个数据。这些成为一个数据的集合;
class里面的数据顺序和数量不能变;
class文件格式由下面几个部分组成
1 魔数与class文件的版本
上面是class文件版本号的表;
前四个字节是魔数,cafebabe,再四个字节是版本号,前两个是副版本号0000,后两个是主版本号0032,十六进制0032转换为十进制是50,也就是版本号是50:JDK6。有的时候有一些新功能进行公测,会把副版本号设置成65535,以区别开来。
2 常量池
下面是17种在常量池里存储的数据类型:
下面是这17种表的具体内容:
下面是上面代码用javap运行后输出的常量表:
首先,前2个字节0016,换算成十进制是22,表示的是常量表包含常量的数量为21个,即1-21,把0这个位置空出来是因为后面如果哪个数据不引用常量池里的数据,就可以把索引值设置为0。
然后接下来是07 对应的是constant_class_info,根据结构和功能,知道后两个字节0002是常量表的一个索引,第二个就是01,也就是constant_utf8_info,长度是001D,也就是十进制29,说明后面29个字节是一个用utf8编写的字符串:6F 72 67 2F 66 65 6E 69 78 73 6F 66 74 2F 63 6C 61 .....73 73 (第三行倒数第四个),通过ASCII码。换算出来的内容为:org/fenixsoft/clazz/TestClass 后面就是同理。全部内容可以参照上面javap输出的常量表
3 访问标志
常量表后面接着两个字节表示访问标志,上面例子是0021,对应0020 + 0001 也就是ACC_PUBLIC和ACC_SUPER,这个java类不是接口,不是注释,不是枚举,不是模块,没有被声明为final,以及不为abstract类。