jvm

137 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置

项u2类型的数据,代表常量池容量计数值

(constant_

pool_count)。与Java中语言习惯不同,这个容量计数是从1而不是0开始的,如下图所示,常量池容

量(偏移地址:0x00000008)为十六进制数0x0016,即十进制的22,这就代表常量池中有21项常量,索引值范

围为1

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

果后面某些指向常量池的索引值的数据在特定情况下需要表达

不引用任何

个常量池项目

的含义,可以把索引

值设置为0来表示。Class文件结构中只有常量池的容量计数是从1开始,对于其他集合类型,包括接口索引集合、

字段表集合、方法表集合等的容量计数都与

般习惯相同,是从0开始。

举例:匿名内部类本身没有类名称,进行名称引用时会将index指向0;Object类的文件结构的父类索引指向0;

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

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

符号引用则属于编译原理方面的概念,主要包括下面几类常量:

·

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

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

·

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

方法的名称和描述符 ·

方法句柄和方法类型(Method Handle、

Method Type、Invoke Dynamic) ·

动态调用点和动态常量(Dynamically

Computed

Call Site、Dynamically

Computed

Constant)