当前位置 : 主页 > 编程语言 > java >

Class文件结构介绍[常量池]

来源:互联网 收集:自由互联 发布时间:2022-07-04
概述   常量池是紧接着主次版本号之后出现的,常量池可以理解为class文件之中的资源仓库,它是Class文件结构中与其他项目管理最多的数据类型,也是占用Class文件空间最大的数据项

概述

  常量池是紧接着主次版本号之后出现的,常量池可以理解为class文件之中的资源仓库,它是Class文件结构中与其他项目管理最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在Class文件中第一个出现的表类型数据项目。案例代码还是和前一篇的一样,如下:

public class Test {

private int a;

public int run(){
System.out.println("波波烤鸭");
return a=1;
}
}

常量池介绍

1.结构

  由于常量池中常量的数量是不固定的,所以常量池的入口需要放置一项u2类型的数据表示常量池容量计数值,如下:
Class文件结构介绍[常量池]_JVM

  本例中常量池中的常量的个数是35个,注意此处和java中的习惯不一样,这个容器的计数是从1而不是从0开始的,上图的结果是36,代表常量池中有35项常量,索引范围为1~35,0项常量有特殊考虑,当表达“不引用任何一个常量池项目”的含义时可以把索引值置为0来标示。
Class文件结构介绍[常量池]_字面量_02
Class文件结构介绍[常量池]_常量池_03

  在constant_pool_count后是一个表数据类型constant_pool其中存储的就是constant_pool_count计数的那35个常量项。

2.存储数据的类型

  常量池中主要存放两大类型常量:字面量(Literal)和符号引用(Symbolic References).

类型

说明

字面量

比较接近java语言层面的常量概念,如文本字符串,声明为final的常量值等

符号引用

属于编译原理方面的概念,包括这三种:

1.类和接口的全限定名

2.字段的名称和描述符

3.方法的名称和描述符

注意:

  • 全限定名中的".“被替换为”/".比如
    Class文件结构介绍[常量池]_Class结构_04
  • 常量池中存储着最基本的信息,不仅程序会用到,而且Class文件本身也会通过#来引用
    Class文件结构介绍[常量池]_Class结构_05
  • 符号引用:
      符号引用以一组符号来描述所引用的目标(com/dpb/test/Test),符号可以是任何形式的字面量,只要使用时能无歧义的定位到目标即可,符号引用和虚拟机实现的内存布局无关,引用的目标并不一定已经加载到了内存中。
    Class文件结构介绍[常量池]_常量池_06
    直接引用
      直接引用可以指向目标的指针、相对偏移量或者是一个能够直接定位到目标的句柄。直接引用于虚拟机的内存布局相关,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不同。如果有了直接引用,那么,所引用的目标一定已经在内存中存在。

    3.表的存储结构说明

      通过观察我们发现,在这14中表中都有些相同的特定,比如表的开始的第一位都是一个u1类型的标志位(tag),代表当前属于哪种类型,具体的标志说明如下:

    类型

    标志(tag)

    描述

    CONSTANT_Utf8_info

    1

    UTF-8编码的字符串

    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

    类中方法的符号引用

    CONSTANT_InterfaceMethodref_info

    11

    接口中方法的符号引用

    CONSTANT_NameAndType_info

    12

    字段或方法的部分符号引用

    CONSTANT_MethodHandle_info

    15

    表示方法句柄

    CONSTANT_MethodType_info

    16

    表示方法类型

    CONSTANT_InvokeDynamic_info

    18

    表示一个动态方法调用点

    参考此表我们就能够看出这35个常量项的类型了。
    Class文件结构介绍[常量池]_描述符_07

      从上面的结构我们也发现不同类型的表数据结构也是不相同的,详细结构如下,参考后会更加详细些。

    常量

    选项

    类型

    描述

    CONSTANT_Utf8_info

    tag

    u1

    值为1

    length

    u2

    UTF-8编码的字符串占用的字节数

    bytes

    u1

    长度为length的UTF-8编码的字符串

    CONSTANT_Integer_info

    tag

    u1

    值为3

    bytes

    u4

    按照高位在前存储的int值

    CONSTANT_Float_info

    tag

    u1

    值为4

    bytes

    u4

    按照高位在前存储的float值

    CONSTANT_Long_info

    tag

    u1

    值为5

    bytes

    u8

    按照高位在前存储的long值

    CONSTANT_Double_info

    tag

    u1

    值为6

    bytes

    u8

    按照高位在前存储的double值

    CONSTANT_Class_info

    tag

    u1

    值为7

    index

    u2

    指向全限定名常量项的索引

    CONSTANT_String_info

    tag

    u1

    值为8

    index

    u2

    指向字符串字面量的索引

    CONSTANT_Fieldref_info

    tag

    u1

    值为9

    index

    u2

    指向声明字段的类或接口描述符CONSTANT_Class_info的索引项

    index

    u2

    指向字段描述符CONSTANT_NameAndType的索引项

    CONSTANT_Methodref_info

    tag

    u1

    值为10

    index

    u2

    指向声明方法的类描述符CONSTANT_Class_info的索引项

    index

    u2

    指向名称及类型描述符CONSTANT_NameAndType的索引项

    CONSTANT_InterfaceMethodref_info

    tag

    u1

    值为11

    index

    u2

    指向声明方法的接口描述符CONSTANT_Class_info的索引项

    index

    u2

    指向名称及类型描述符CONSTANT_NameAndType的索引项

    CONSTANT_NameAndType_info

    tag

    u1

    值为12

    index

    u2

    指向该字段或方法名称常量项的索引

    index

    u2

    指向该字段或方法描述的索引

    CONSTANT_MethodHandle_info

    tag

    u1

    值为15

    reference_kind

    u2

    值必须在[1,9]之间,它决定了方法句柄的类型,方法句柄类型的值表示方法句柄的字节码行为

    reference_index

    u2

    值必须是对常量池的有效引用

    CONSTANT_MethodType_info

    tag

    u1

    值为16

    descriptor_index

    u2

    值必须是对常量池的有效引用,常量池在索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符

    CONSTANT_InvokeDynamic_info

    tag

    u1

    值为18

    bootstrap_method_attr_index

    u2

    值必须是当前Class文件中引导方法表的bootstrap methods[]数组的有效索引

    name_and_type_index

    u2

    值必须是对当前常量池的有效索引,常量池在该处的索引必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符

    参考《深入理解Java虚拟机》


    网友评论