class文件结构

来源:互联网 发布:图片上传到淘宝变模糊 编辑:程序博客网 时间:2024/06/02 05:40

概述

  Java虚拟机实现了语言无关性的关键在它不和包括Java在内的任何语言绑定,它只与“class文件”这种特定的二进制文件格式关联,Class文件中包括了Java虚拟机指令集和符号表以及其他辅助信息,编程语言语言只要实现自身的编译器,将源码编译成class文件,即可以在JVM上运行。时至今日,商业机构和开源机构已经在Java语言之外发展出了一大批在Java虚拟机之上运行的语言,如Clojure、Groovy、JRuby、Jython、Scala等。
  

两种数据类型

  Class文件以8位字节为基本单位,各个数据项严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符。
  Class文件使用无符号数和表两种数据类型来存储数据。

1、无符号数:用u1、u2、u4、u8分别表示1、2、4、8个字节,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值

2、:由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾,整个Class文件本质上就是一张表,由下图所示的数据项构成。

  无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这时称这一系列连续的某一类型的数据为某一类型的集合。

魔数与Class文件的版本

  每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。
  紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次号(Minor Version),第7和第8个字节是主版本号(Major Version)。高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件。

常量池

具体参见:class文件常量池

访问标志

  在常量池结束之后,紧接着的两个字节代表访问标志(access_flags),这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等。

类索引、父类索引与接口索引集合

  类索引(this_class)是一个u2类型的数据,用于确定这个类的全限定名
  父类索引(super_class)是一个u2类型的数据,父类索引用于确定这个类的父类的全限定名
  接口索引集合(interfaces)是一组u2类型的数据的集合
  Class文件中由这三项数据来确定这个类的继承关系

字段表集合

字段表(field_info)用于描述接口或者类中声明的字段变量
字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量
name_index是对常量池的引用,代表着字段的简单名称

描述符

  descriptor_index是对常量池的引用,代表字段的描述符
  对于数组类型,每一维度将使用一个前置的“[”字符来描述,如一个定义为“java.lang.String[][]”类型的二维数组,将被记录为:“[[Ljava/lang/String;”,一个整型数组“int[]”将被记录为“[I”用描述符来描述方法时,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内。

1、void inc()的描述符为”()V”
2、java.lang.String toString()的描述符为”()Ljava/lang/String;”
3、int indexOf(char[]source, int sourceOffset, int sourceCount,char[] target, int targetOffset, inttargetCount, int fromIndex)的描述符为 “([CII[CIII)I”

方法表集合

  方法表的结构如同字段表一样,依次包括了访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)几项。

属性表集合

具体参见:属性表集合