对常量池的认识

常量池可以理解为Class文件之中的资源仓库,它是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时他还是在Class文件中第一个出现的表类型数据项目。
由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与java中语言习惯不一样的是,这个容器计数是从1而不是0开始的,如图6-3所示,常量池容量(偏移地址:0x00000008)为十六进制数0x0016,即十进制的22,这就代表常量池中有21项常量,索引值范围为1~21。在Class文件格式规范制定之时,设计者将第0项常量空出来是有特殊考虑的,这样做的目的在于满足后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义,这种情况就可以把索引值置为0来表示。Class文件结构中只有常量池的容量计数是从1开始,对于其他集合类型,包括接口索引集合,字段表集合,方法表集合等的容量计数都与一般习惯相同,是从0开始的。
对常量池的认识_第1张图片 常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symantec References)。字面量比较接近于java语言层面的常量概念,如文本字符串,声明为final的常量值等。而字符号引用则属于编译原理方面的概念,包括下面的三类常量:
1.类和接口的权限名(Fully Qualified Name)
2.字段的名称和描述符(Descriptor)
3.方法的名称和描述符
java代码在进行javac编译的时候,并不像C和C++那样有“连接”这一步骤,而是在虚拟机加载Class文件的时候进行动态连接,也就是说,在Class文件中不会保存各个方法,字段的最终内存布局信息,因此这些字段,方法的符号引用不经过运行期转换的话无法得到真正的内存入口地址,也就无法被虚拟机使用。当虚拟机运行时,需要从常量池获得对应得符号引用,再在类创建时或运行时解析,翻译到具体的内存地址之中。

你可能感兴趣的:(对常量池的认识)