java类文件结构

任何Java程序都要通过jvm虚拟机的处理生成class文件,而后而后虚拟机去解析class文件,下面咱们来介绍一下class文件的结构。java

  Class文件格式采用的是相似于C语言的结构体的伪结构来存储数据,这种伪结构只有两种数据类型:无符号数和表;jvm

  无符号数属于基本的数据类型,以u1,u2,u3,u4,u8来表明1个字节、2个字节、4个字节、8个字节的无符号数,无符号数能够用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值;工具

  表是由多个无符号数或者是其余表做为数据项构成的复合数据类型,全部表都习惯以“_info”结尾。整个Class文件本质上就是一张表。编码

  Class文件不像XML文件那样,因为没有任何的分隔符号,因此对于顺序和数量,甚至于数据存储的字节序这样的细节,都是被严格限定的,哪一个字节表明什么顺序,长度是多少,都是不容许改变的。spa

  每一个Class文件的头4个字节都称为魔数,它的惟一做用就是判断该文件是不是一个能被虚拟机接收的Class文件。紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节存储的是次版本号(Minor Version),第7和第8个字节存储的是主版本号(Major Version),Java版本号是从45开始的。翻译

  下面分析一个简单的Java程序对应的Class文件code

  源文件
索引

class Test0 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
                System.out.println("123");

    }

}

对应的Class文件接口


这里的第八个字节值对应的十进制就是50,该版本号说明这个文件是能够被JDK1.6或者以上版本虚拟机执行的Class文件。内存


紧接着主次版本号以后的是常量池入口,常量池能够理解为Class文件中的资源仓库,因为常量池中的常量数量不固定的,因此统一在和常量池的入口处须要存放一个u2(两个字节)类型的数据,表明常量池容量计数值,与Java中语言习惯不同的是,这个计数是从1开始的而不是从0开始,Class文件中只有常量池的容量计数是从1开始的,对于其余的集合类型,包括接口索引集合,字段表集合,方法表集合等的容量计数都是从0开始的,图中0x001D表示的十进制数29表示常量池中有28项常量。字节码的转化按照十六进制ASCII标准

常量池中主要存放两大类常量:字面量和符号引用,字面量比较接近Java语言层次的常量概念,如文本字符串,申明为final的常量值等,而符号引用则属于编译原理方面的概念,包括下面三类常量:类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。  当虚拟机运行时,就会从和常量池中获取对应的符号引用,再在类建立或者运行时解析,翻译到具体的内存地址之中。(常量池中的每一项常量都是一个表,JDK1.7中又额外增长了3种表结构数据,拥有14种表结构数据)。

 

如表1-1是常量池的项目类型

能够看出,示例Class中第一项常量,它的标志位是0x0A,查表1-1可知这个常量属于CONSTANT_Methodref_info类型,此类型的常量表明类中方法的符号引用。

     之因此说常量池是最烦琐的数据,是由于这14种常量类型各自拥有本身的结构。

本例中一共有28个常量,其他的27个常量咱们能够交由Oracle提供的专门用于分析Class文件字节码的工具:Javap;效果如图1-1


图1-1  使用Javap命令输出常量表


未完待续。。。

相关文章
相关标签/搜索