第三篇 Java类文件结构

来源:互联网 发布:怎么备案域名 编辑:程序博客网 时间:2024/06/06 13:54

Java类文件结构

一、概述

Java实现了跨平台,“一次编译,到处运行”。实现平台语言无关性的基础仍然是虚拟机的字节码存储格式。使用javaJRuby等其他语言的编译器都可以将程序编译成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)魔数、(2class文件的版本号、(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文件。(很多文件例如jpgpng格式的文件都是通过魔数来区分的,并不是后缀名,因为后缀名是可以更改的,不安全)。

   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,这个表示项目类型选中的是7CONSTANT_Class_info,接着0x 0002表示的是常量u2:name_index.

紧接着回到项目类型标志位中设定tag = ox01,后面设置的是length.ox001D,也就是29位,紧接着29位表示的就是数据内容。

现在,图1.1中的内容应该就差不多理解了。

 

其他类型的我们在这里省略了。

4、访问标志位:

        紧接着常量位,是访问标志位。这个标志位用于识别一些类或是接口层次的访问信息,包括:这个class是类还是接口,是否定义类型为pulbic类型,是否为final等等。

5、类索引、父亲索引与接口索引集合:

   Class文件由这三项来确定这个类的继承关系。类索引、父类索引和接口索引都按顺序排列在访问标志之后。

6、字段表集合:

   字段表用于描述 接口或类中声明的变量。字段包括了类级别变量或实例级别变量,但不包括在方法内部声明的变量。

例如有:字段的作用域(publicprivateprotected等),staticfinal等。

 字段表集合包括以下内容(注意下面四个并不是并列的,而是包含关系):





1 0