实现语言无关性的基础仍然是虚拟机和字节码存储格式,使用Java编译器可以把Java代码编译为存储字节码的Class文件,
使用JRuby等其他语言的编译器一样可以把程序代码编译成Class文件,虚拟机并不关心Class的来源是什么语言,只要他符合Class文件应用的结构就可以在Java虚拟机中运行。
Class文件是一组以八位字节为基础的单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部都是程序运行的必要数据,没有空隙存在。当遇到需要八位字节以上的空间的数据项时,则会按照高位在前分割方式分割成若干个八位字节进行存储。
根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种结构只要两种数据类型:无符号数和表。
无符号数属于基本的数据类型。
表是由多个无符号数或者其他表作为数据项构成的复合数据类型。
魔数
每个class文件的头4个字节称为魔数,它的唯一作用是用来确定这个文件是否为
一个能被虚拟机接收的class文件。紧着接魔数的4个字节存储的是Class文件的
版本号,5、6字节是次版本号,7、8字节是主版本号,java的版本号是从45开始
的。
常量池
紧接着主次版本号之后是常量池入口,常量池是Class文件结构中与其它项目关
联最多的数据类型,也是占用Class文件空间最大的数据项目之一,用于常量池
的数量是不固定的,所以需要在常量池的入口放置一个常量池容量计数值,这个
计数器是从1开始而不是从0开始,因此如果计数器的值为18,表示有17个常量。
作Class文件格式规范的时候,将第0项常量空出来是有特殊考虑的,可以用来表
示不引用任何常量池。
常量池之中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。
字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为finla的常量值等。
而符号引用则属于编译原理方面的概念,包括下面三个常量:
·类和接口的权限类名
·字段的名称和描述符
·方法的名称和描述符
Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这一步骤,而
是在虚拟机加载Class文件的时候进行动态连接。
访问标志位
在常量池结束之后,紧着着的2字节代表访问标志,这个标志用于识别一些类或
接口层次的访问信息,包括:这个Class是类还是接口,是否定义为public类型,
是否定义为abstract类型;如果是类的话,是否被声明为final等
字段值集合
方法表集合
在java语言中,要重载一个方法,除了要与原方法具有相同的简单名称之外,还
要求必须拥有一个与原方法不同的特征签名,特征签名就是一个方法中各个参数
在常量池中的字段符号引用的集合,也就是因为返回值不会包含在特征签名之中,
因此java语言里是无法仅仅依靠返回值的不同来对一个已有方法进行重载的。但
是在Class文件格式中,只要描述符不是完全一致的两个方法也可以共存,也就
是说如果两个方法有相同的名称和特征签名,但返回值不同,那么也是可以合法
共存于同一个Class文件中的。