jvm 什么是常量池,常量池定义 class常量池

首先需要理解下Java的class文件,以及class文件结构:

1.Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文 件之中,中间没有任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割 成若干个8个字节进行存储

    注: 任何一个Class文件都对应着唯一的一个类或接口的定义信息,但是反过来说,类或 接口并不一定都得定义在文件里(譬如类或接口也可以动态生成,直接送入类加载器中)

2.Class文件格式采用类c语言结构体的伪结构来存储数据

            结构:

                      a. 无符号数

                      b.

      a.无符号数属于基本数据类型,u1:代表1个字节无符号数,有四个参数 u1, u2, u4, u8。 它们们用来描述数组,索引引用,数量值或字符串

      b. :无符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名 都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上也可以视 作是一张表,这张表由下图所示的数据项按严格顺序排列构成

 3. 图中的constant_poll 即常量池,是class中的表结构(类型cp_info)

 4. 常量池可以比喻为class文件存放的资源仓库,它是class结构中与其他项目引用最多的数据,通常也是占用class文件空间最大的数据项目之一

 5. 常量池入口为u2类型数据,为常量池容量计数值,常量池中有21项常量。索引范围1~21

 6. 常量池存放类型

     a. 字面量(Literal)

     b. 符号引用(Symbolic References)

   字面量: 文本字符串,声明为final的常量值等

   符号引用:

                    ·被模块导出或者开放的包(Package)

                    ·类和接口的全限定名(Fully Qualified Name)

                    ·字段的名称和描述符(Descriptor)

                    ·方法的名称和描述符

                    ·方法句柄和方法类型(Method Handle、Method Type、Invoke Dynamic)

                    ·动态调用点和动态常量(Dynamically-Computed Call Site、Dynamically-Computed Constant)

7. class文件不会保存方法,或字段的值而是通过常量池进行转换使用。虚拟机进行类加载时,从常量池获取到字面量(一些常量值),符号引用(指针引用数据),在类创建或运行时解析,从常量池拿到这些数据,到具体的内存地址之中。(我认为与将代码中的魔法值,类似1,2,字符串等抽出来,单独放到一个类中类似,常量池就是做这个的)

8.常量池每一项常量都是一个表,截止jdk13,一共有17种不同类型常量:

9. 总结来说,常量池就是存储类中(编译后的class文件):字符串的值,final常量,方法引用,方法描述,方法类型等的表结构

猜你喜欢

转载自blog.csdn.net/qq_33919114/article/details/132476852