『JVM』Class文件结构

 

查看十六进制的Class文件:IDEA插件 - BinEd

 

Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,

主要有两类数据项,无符号数和表,无符号数用来表述数字,索引引用以及字符串等

 如:u1、u2、u4、u8分别代表1个字节、2个字节、4个字节、8个字节

名称 类型 数量
magic(魔术) u2 1
minor_version(次版本号)  u2  1
major_version(主版本号)  u2  1
constant_pool_count(常量池数量)  u2  1
constant_pool(常量池表)  cp_info  constant_pool_count-1
access_flags(类的访问控制权限)  u2  1
this_class(当前类名)  u2  1
super_class(父类)  u2  1
 interfaces_count(接口个数)  u2  1
 interfaces(接口名) u2   interfaces_count
 fields_count(属性的个数) u2   1
 fields(属性)  field_info  fields_count
 methods_count(方法的个数) u2  1
 methods(方法)  method_info  methods_count
 attributes_count(附加属性的个数) u2   1
 attributes(附加属性的表)  attribute_info  attributes_count

 

魔数和java版本号(0x表示十六进制)

每个Class文件的头4个字节被称为魔数(Magic Number)它的唯一作用是确定这个文件是否能被虚拟机接受的Class文件。

值为0xCAFEBABE      

紧接着魔数的4个字节存储的是Class文件的版本号: 第5和第6个字节是次版本号(minor_version)

                           第7和第8个字节是主版本号(major_version)

 

  0X0034(对应十进制的50):JDK1.8      
  0X0033(对应十进制的50):JDK1.7      
  0X0032(对应十进制的50):JDK1.6      
  0X0031(对应十进制的49):JDK1.5  
  0X0030(对应十进制的48):JDK1.4  
  0X002F(对应十进制的47):JDK1.3  
  0X002E(对应十进制的46):JDK1.2 

 

 这里可以得出我们使用的版本为java1.8,16进制的34等于10进制的52

 

常量池

紧接着主、 次版本号之后的是常量池入口, 常量池可以比喻为Class文件里的资源仓库, 它是Class文件结构中与其他项目关联最多的数据,

通常也是占用Class文件空间最大的数据项目之一, 另外, 它还是在Class文件中第一个出现的表类型数据项目 ,

常量池的入口需要放置一项u2类型的数据, 代表常量池容量计数值(constant_pool_count) ,这个容量计数是从1开始的。

如下图所示:常量池容量(偏移地址: 0x00000008) 为十六进制数0x0013,则十进制为19,则这里有18个长常量,索引范围为1-18,

在Class文件格式规范制定之时, 设计者将第0项常量空出来是有特殊考虑的, 这样做的目的在于,

如果后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义, 可以把索引值设置为0来表示。

 

常量池紧跟着就是第一个常量的标志 0x0A,十进制为10

查找下图中 constant_pool(常量池表)10号

 

 

类的访问控制权限(access_flags)

接下来的2个字节代表访问标志位,这个标志用于识别类或接口层次的访问信息,如:这个Class是类还是接口,是否定义为public类型

 

posted @ 2020-08-26 13:30  打工人  阅读(189)  评论(0编辑  收藏  举报