Java虚拟机-class文件

1.class文件概述

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目按照顺序紧凑的摆列在Class文件之中,中间没有添加任何分隔符,整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在当遇到8位字节以上的空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。Class文件中有两类数据类型,分别是无符号数和表,具体包括:魔数,Class文件版本,常量池,访问标志,类索引,父类索引,接口索引集合,字段表集合,方法表集合,属性表集合。

2.class文件格式

类型 名称 数量 
u4 magic 1
u2 minor_version 1
u2 major_version 1
u2 constant_pool_count 1
cp_info constant_pool constant_pool_count - 1
u2 access_flags 1
u2 this_class 1
u2 super_class 1
u2 interface_count 1
u2 interfaces interface_count
u2 fields_count 1
field_info fields fields_count
u2 methods_count 1
method_info methods methods_count
u2 attributes_count 1
attribute_info attributes attributes_count

3.魔数

字节码的前四个字节标识文件的类型,用于在执行Class文件时校验文件是否为class文件,.class的文件魔数为CAFEBABE。

4.Class文件版本

魔数后4个字节表示的是Class文件的版本,后面两位表示主版本号,前面3个字节为次版本号。对应关系如下表:

JDK1.8 52
JDK1.7 51
JDK1.6 50
JDK1.5 49
JDK1.4 48
JDK1.3 47
JDK1.2 46
JDK1.1 45

5.常量池

版本号后2个字节为常量池的长度。之后为常量池。

  cp_info format  
type descriptor remark
u1 tag  
u1 info[]  
  CONSTANT_Methodref_info
用于记录方法信息(包括类中定义的方法以及代码中使用到的方法)
 
type descriptor remark
u1 tag CONSTANT_Methodref(10)
u2 class_index constant_pool中的索引,CONSTANT_Class_info类型。记录定义该方法的类。
u2 name_and_type_index constant_pool中的索引,CONSTANT_NameAndType_info类型。指定类中纯方法名(name)和方法描述符(descriptor)
  CONSTANT_fieldref_info  
type descriptor remark
u1 tag  
u2 index  
u2 index  
  CONSTANT_Class_info
用于记录类或接口名
 
type descriptor remark
u1 tag CONSTANT_ClassI(7)
u2 name_index constant_pool中的索引,CONSTANT_utf8_info类型。表式类或接口名。
  CONSTANT_Utf8_info  
type descriptor remark
u1 tag  
u2 length  
u1 bytes  

各常量池和index对应关系如下表:

CONSTANT_Utf8_info 1
CONSTANT_Integer_info 3
CONSTANT_Float_info 4
CONSTANT_Long_info 5
CONSTANT_Double_info 6
CONSTANT_Class_info 7
CONSTANT_String_info 8
CONSTANT_Fieldref_info 9
CONSTANT_Methodref_info 10
CONSTATN_Interfacemethodref 11
CONSTANT_NameAndType_info 12
CONSTATN_MethodHandle_info 15
CONSTANT_MethodType_info 16
CONSTANT_Dynamic_info 18

6.访问标志符

java字节码用两个字节来表示访问标志。

Flag Name Value Remarks
ACC_PUBLIC 0x0001 public
ACC_FINAL 0x0010 final
ACC_SUPER 0x0020 用于兼容早期编译器,新编译器都没有设置该标记,以在使用invokespecial指令时对子类方法做特定处理。
ACC_INTERFACE 0x0200 接口,同时需要设置:ACC_ABSTRACT。不可同时设置ACC_FINAL、ACC_SUPER、ACC_ENUM。
ACC_ABSTRACT 0x0400 抽象类,无法实例化。不可与ACC_FINAL同时设置。
ACC_SYNTHETIC 0x1000 synthetic,由编译器产生,不存在于源代码中。
ACC_ANNOTATION 0x2000 注解类型,需同时设置:ACC_INTERFACE、ACC_ABSTRACT。
ACC_ENUM 0x4000 枚举类型
7.类索引

this_class:类索引,super_class:父类索引,interface_count:类实现的接口数量,interfaces:类实现的接口索引。

8.字段表集合

字段表用于描述接口或者类中声明的变量。


一个类中字段的作用域,静态或者非静态,可变形,并发可见性,是否可以序列化都由一个2个字节的access_flags标识,数据类型由descriptor_index标识,字段名称由name_index标识,其他属性由attribute_count和attribute_info标识。

8.方法表集合

方法表集合用来描述类或接口中定义的方法。

Method_info {
acccess_flags u2      --访问标志
name_index u2         --方法名索引
description_index u2 --方法描述索引
attributes_count u2  --属性表长度
attribute_info u2      --属性表信息

}

9.属性表集合

属性表集合用来补充表述字段表和方法表中的信息。

attribute_info {
attribute_name_index u2 --属性名索引
attribute_length u4         --属性长度
info u1                          --属性信息
}

猜你喜欢

转载自blog.csdn.net/qq_22866497/article/details/80673700