浅谈JVM(五)——字节码文件ClassFile

Java代码被前端编译器javac成功编译为一个符合Java虚拟机规范的字节码文件,然后JVM读取运行字节码文件。那么我们平常写的java代码编译后的字节码文件是怎样的呢?以及怎样的字节码文件符合规范的呢?

一般来说ClassFile文件结构如下;

ClassFile{
    u4          magic;
    u2          minor_version;
    u2          major_version;
    u2          constant_pool_count;
    cp_info     constant_pool[constant_pool_count-1];
    u2          access_flags;
    u2          this_class;
    u2          super_class;
    u2          interface_count;
    u2          interfaces[interface_count];
    u2          fields_count;
    field_info      fields[fields_count];
    u2              methods_count;
    method_info     methods[methods_count];
    u2              attributes_count;
    attribute_info  attributes[attributes_count];
}

注意:u4表示4个字节无符号,后缀_info表示一张表。

  • magic:魔术,用于JVM校验字节码文件是否有效且合法。
  • minor_versionmajor_version:表示字节码文件的版本号,如果字节码文件的版本号超出了JVM能够处理的范围,则JVM不会处理这个字节码文件。
  • constant_pool_countconstant_pool:常量池计数器和常量池,常量池主要放置字面量和符号引用,常量池计数器则是来表示常量项的数量。
  • access_flags:访问标志,主要是表示某一个接口或者类的访问权限,如:public,final,abstract等。
  • this_classsuper_class:分别表示类索引和父类索引,通过父类索引可以知道当前类的父类;类索引相当于当前类的全限定名。
  • interface_countinterfaces:接口计数器用于表示当前类的或者接口的接口数量,接口表则表示接口的索引集合。
  • methods_countmethods:方法计数器表示methods(方法表的数量),而methods表示一个数组集合,一个methods表描述了一个方法完整信息。
  • attributes_countattributes:属性计数器表示当前类属性表的数量,属性表是一个数组集合,属性表中每一项都是attribute_info的数据项。

常量池

常量池主要存放了两大类常量:字面量和符号引用。字面量类似于java的常量;而符号引用属于编译原理的概念了包括了类和接口的全限定名,字段的名称和描述符以及方法的名称和描述符。当JVM运行时,根据从常量池获得的符号引用,将类中的接口,方法等加载到具体的内存中。

访问标志

访问标志用于识别这个Class是类还是接口;是否定义为public、abstract还是final。访问标志一共有16个标志位可以用,当前值定义了其中的8个,没有使用到的要求为0。

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

类索引用于确定当前类的全限定名,父类索引用于确定当前类的父类全限定名,所以除了java.lang.Object以外,所有的java类的父索引都不为0.接口索引集合描述了这个类实现了哪些接口,按照implements的顺序排列。

字段表集合

字段表用于描述变量的信息。字段表的结构如下

类型 名称 数量
u2 access_flags 1
u2 name_index 1
u2 descriptor_index 1
u2 attributes_count 1
attribute_info attributes attributes_count

access_flags用来描述字段的访问标志,name_index和descriptor_index分别代表了字段的名称和字段、方法的描述符。
attributes_count表示属性表集合大小,attributes表用来描述属性的额外信息。

方法表集合

方法表和字段表的结构几乎一模一样,如同字段表一样,方法表的结构依次包括了访问标志、名称索引、描述符索引、属性表等。

类型 名称 数量
u2 access_flags 1
u2 name_index 1
u2 descriptor_index 1
u2 attributes_count 1
attribute_info attributes attributes_count

仅仅在访问标志有些不同(有些变量的访问限制和方法不同,如方法里面没有volatile和transient修饰,而多了native、abstract等)。

你可能感兴趣的:(JAVA,JVM,jvm,java)