JVM入坑(三) - .class文件结构分析(2):常量池

关于静态常量池

.class文件中的常量池 ( Constant Pool ) 也叫做静态常量池,是存放常量数据的地方。
熟悉c/c++的人可能对于常量第一反应是:constan修饰的变量,但是在此处提到的常量范围更加广泛一些,在java中提到的常量是指:在运行中所有不会再发生变化的数据。比如类的名字、方法的名字、方法所属的类、方法的参数、方法的返回值类型、定义的常量(也就是c/c++中的const修饰的变量),所以可以发现,这个常量池里存放的数据非常的丰富。

这一部分很重要,里面的常量项会在后续的方法表、字段表等地方大量被引用。

1、常量池存放的内容

常量池中主要存放两大类型常量项:字面量(literal)与符号引用(symbolic references)
1、字面量:由字符、数字等构成的字符串或者数值统称为字面量,并且字面量必须作为右值出现(即等号右边的值)
比如:int a = 123;String s = “hollis”;
123和"hollis"就被称为字面量。

2、符号引用:用一组符号来描述所引用的目标,符号引用的内容可以是任意形式的字面量,只要能根据符号引用精确的定位到目标即可。当使用javac将java程序编译成.class文件时,.class文件并无法知道方法、字段在内存中的最终布局(因为还没有被JVM后期编译),此时在.class文件中就需要将这些的方法、字段用符号引用代替真正的内存地址,直到类加载的解析阶段再用直接引用替换掉符号引用。

符号引用主要包括三类:类和接口的全限定名、字段的名称和描述、方法的名称和描述符

常量池项的细化和分类:

常量池类型划分图

将常量池与常量项图形化后如下:
静态常量池图形化
注意
图中可以看出,常量项#0为预留,.class文件规范中提到过:“指向#0表示不知向常量池任何一项”。所以constant_pool_pool - 1才是有效常量项的数量,有效常量项是从#1开始的,最后一个有效常量项为constant_pool_count - 1

Javap反编译后的静态常量池截图示例,后面会有专门的代码和constant pool进行分析:
截取javap反编译结果中的静态常量池部分的示例

2、常量池各个项目类型(cp_info)详解

常量池中的每一个常量项都可以当作一张表,这些表都具有一个特点,就是表的第一个字节是用来声明该常量项的标志位,表示当前常量项属于哪个类型,见下表:

类型 标志
CONSTANT_Utf8_info 1
CONSTANT_Integer_info 3
CONSTANT_Float_info 4
CONSTANT_Long_info 5
CONSTANT_Double_in
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值