《深入理解Java虚拟机》笔记-类文件结构

各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码是构成平台无关性的基石。

1. Class类文件的结构

  • Class文件是以8位字节为基础单位的二进制流,各个数据项紧凑地排列在Class文件中,没有任何分隔符。
  • 采用类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。
  • 无符号数以u1、u2、u4、u8分别代表1,2,4,8个字节无符号数。可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成的字符串值。
  • 表是由多个无符号数或者其他表作为数据项构成的复合数据类型。习惯性的以“_info”结尾。
  • 魔数:每个Class文件的头4个字节。0xCAFEBABE
  • Class文件的版本号:紧接着魔数的四个字节是Class文件的版本号,第5和6字节是次版本号,第7和8是主版本号。JDK7对应51.0
  • 常量池:是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,也是Class文件中第一个出现的表类型数据项目。

      常量池的入口放置一项u2类型的数据。代表常量池容量计数值(constant_pool_count)

  1. 常量池主要放两类常量:字面量和符号引用。字面量如文本字符串、声明为final的常量值等。符号引用包括:类和接口的全限定名;字段的名称和描述符;方法的名称和描述符。
  2. 每一个常量都是一个表,JDK1.7共有14种表,表的第一位是一个u1类型的标志位。

常量池的项目类型

类型标志描述
CONSTANT_Utf8_info1UTF-8编码的字符串
CONSTANT_Integer_info
2整形
CONSTANT_Float_info
3浮点型
CONSTANT_Long_info
4长整型
CONSTANT_Double_info
5双精度型
CONSTANT_Class_info
6类或接口的符号引用
CONSTANT_String_info
7字符串类型
CONSTANT_Fieldref_info
8字段的符号引用
CONSTANT_Methodref_info
9类中方法的符号引用
CONSTANT_InterfaceMethodref_info
10接口中方法的符号引用
CONSTANT_NameAndType_info
11字段或方法的部分符号应用
CONSTANT_MethodHandle_info
12表示方法句柄
CONSTANT_MethodType_info
13标识方法类型
CONSTANT_InvokeDynamic_info
14表示一个动态方法调用点

这14种常量类型均有自己的结构。1由tag(u1)、length(u2)、bytes(u1)组成;2-5有tag、bytes组成;6-11由tag、index(u2)、index组成。

  • 访问标志:常量池结束之后,紧接着的两个字节代表访问标志。用于标识类或接口的访问信息。
  • 类索引(u2)、父类索引(u2)、接口索引集合按顺序排在访问标志之后。类索引和父类索引分别指向一个类型为CONSTANT_Class_info的类描述符常量,对应一个全限定名字符串。接口索引集合
  • 字段表集合:用于描述类中或接口中声明的变量,但不包括方法内部声明的变量。结构为access_flags(u2)、name_index(u2)、descriptor_index(u2)、attributes_count(u2)、attributes(类型:arrtibute_info 数量:attributes_count)。 全限定名是把类全名中的.换成/,比如“org/qr/edu/Test”;简单名称是方法或字段的名称比如getMax、count等;描述符作用是描述字段的数据类型、方法的参数列表、返回值,如“[[Ljava/lang/String”代表“java.lang.String[][]”类型的二维数组,“I[”代表整型数组“int[]”,“()Ljava/lang/String”为方法“java.lang.String toString”的描述符。
  • 方法表集合:方法表的结构和字段表一样,含义也类似,仅在访问标志和属性表集合的可选项中有区别。方法里的代码经过编译器编译成字节码指令后,存放在方法属性表集合中一个名为“Code”的属性里面。重载方法时,需要有不同的特征签名。
  • 属性表集合:Class文件、字段表、方法表都可以携带自己的属性表集合,用于描述某些场景专有的信息。属性表的结构应满足:attribute_name_index(u2)、attribute_length(u4)、info(类型:u1 长度:attribute_length)。java程序方法体重的代码经过Javac编译器处理之后,最终变成字节码指令存储在Code属性内。
    原文作者:java虚拟机
    原文地址: https://blog.csdn.net/qr457535344/article/details/80932097
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞