Java类文件结构
一、概述
Java实现了跨平台,“一次编译,到处运行”。实现平台语言无关性的基础仍然是虚拟机的字节码存储格式。使用java、JRuby等其他语言的编译器都可以将程序编译成class文件,虚拟机并不关心class文件的来源是什么,只要它符合class文件的结构就可以在java虚拟机上运行了。
二、class类文件的结构概述:
1、基本内容: Class文件是一组以字节(8位)为单位的二进制流,各个数据项严格按照顺序紧凑地排列在class文件中,中间没有任何分隔符,这使得class文件的所有内容几乎全部成为程序运行的必要数据。当然,存储数据项时,有的数据是大于8位的,这时则会按照高位在前的方式分割成若干个8位字节进行存储。
2、具体存储结构分类:
根据java虚拟机规范规定,class文件格式采用一种类似C语言体系结构的伪结构来存储,这种伪结构只有两种数据类型:无符号数和表。
无符号数:属于基本的数据类型,可以用来描述数字、索引引用、数量值,或者按照UTF-8编码构成的字符串值。
表:是由多个无符号数或其他表作为数据项构成的复合数据类型。所有表习惯以“_info”结尾。(整个class文件就是一张表)。
强调:class的结构不像xml等描述语言,由于它没有任何分隔符,每个字节的顺序长度等都不允许改变或是调换。
三、class类文件的结构详述:
Class类文件由以下几部分组成:
(1)魔数、(2)class文件的版本号、(3)常量池、(4)访问标志、(5)类索引、父亲索引与接口索引集合、(6)字段表集合、(7)方法表集合、(8)属性表集合。
首先给出一个样例,接着按照样例说明每个组成部分的含义:
图1.1
注意:上面蓝色底部线和绿色底部线经过的部分共同构成了常量位(后面一部分的也是,之后说明)。
接着上面的介绍,我们进行下面的分析。常量池完了之后紧接着的是下面的访问标志位。
类索引、父亲索引与接口索引集合:OX0001,OX0003,OX0000分别表示类索引为1, 父类索引为3、接口索引集合大小为0.
字段表集合:ox0001:fields_count; ox0002:access_flags; ox0005:name_index,
Ox0006:description_index.
详细介绍:
1、魔数:
每个class文件的头四个字节称为魔数,它的唯一作用是用于确定这个文件是否为一个能被虚拟机接收的class文件。(很多文件例如jpg、png格式的文件都是通过魔数来区分的,并不是后缀名,因为后缀名是可以更改的,不安全)。
Java 虚拟机class文件的魔数规定为:OXCAFEBABE
2、版本号:
版本号分为次版本号 和 主版本号。各占两个字节。
JDK 1.7 版本号为 51; JDK1.6 为50
3、常量池:
常量池是class文件结构中与其他项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一。同时它是表类型的(是第一个出现表类型存储结构的数据项目)。
常量池包括下面几项:
(1)常量池容量计数值:因为常量池长度是不固定的,所以应该有一个容量计数池来计数。 需要注意的是:常量池容量计数器是从1开始计数的,其他都是从0开始。
紧接着常量计数器之后,常量池中主要存放两大类常量:字面量 和 符号引用。
自面量:字面量比较接近于java语言层面的常量概念,如文本字符串、被申明的final常量等。
符号引用:属于编译原理方面的概念。基本包括了以下几个方面:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。
(2)常量池项目类型标志位:(注意标志位没有2号)
总共是11种。但是这11种常量类型各自均有自己的结构。
例如:
图1.1分析:从常量池开始,容量计数器完后接着是OX 07,这个表示项目类型选中的是7号CONSTANT_Class_info,接着0x 0002表示的是常量u2:name_index.
紧接着回到项目类型标志位中设定tag = ox01,后面设置的是length.为ox001D,也就是29位,紧接着29位表示的就是数据内容。
现在,图1.1中的内容应该就差不多理解了。
其他类型的我们在这里省略了。
4、访问标志位:
紧接着常量位,是访问标志位。这个标志位用于识别一些类或是接口层次的访问信息,包括:这个class是类还是接口,是否定义类型为pulbic类型,是否为final等等。
5、类索引、父亲索引与接口索引集合:
Class文件由这三项来确定这个类的继承关系。类索引、父类索引和接口索引都按顺序排列在访问标志之后。
6、字段表集合:
字段表用于描述 接口或类中声明的变量。字段包括了类级别变量或实例级别变量,但不包括在方法内部声明的变量。
例如有:字段的作用域(public、private、protected等),static、final等。
字段表集合包括以下内容(注意下面四个并不是并列的,而是包含关系):