当前位置: 首页 > >

Class类文件结构之常量表

发布时间:

jvm目录

我们已知的在Class文件里,常量池占的比重是非常大的,其它结构中或多或少的都要通过索引来常量池获取它们所需要的信息。但常量分为哪几种类型呢,常量又是如何存储的呢,这是我们本博客的所要讲解的内容具体关于常量池的其它问题,请参考Class类文件结构 的常量池一节常量表(cp_info)的类型主要分为两大类:字面量(Literal)和符号引用(Symbolic References);常量表共有11种表结构,这些表的相同的部分以及区分的方法在于,它们表结构的第一位都是类型为u1称为“tag”的值,根据tag值的不同来区分究竟是属于什么结构的常量表;如下表是11种不同功能的常量表简单说明及tag值。

类型tag值所属类别类型描述
CONSTANT_Utf8_info1字面量UTF-8编码的字符串
CONSTANT_Integer_info3字面量整型字面量
CONSTANT_Float_info4字面量浮点型字面量
CONSTANT_Long_info5字面量长整型字面量
CONSTANT_Double_info6字面量双精度浮点型字面量
CONSTANT_Class_info7符号引用类或接口的符号引用
CONSTANT_String_info8字面量字符串类型字面量
CONSTANT_Fieldref_info9符号引用字段的符号引用
CONSTANT_Methodref_info10符号引用类中方法的符号引用
CONSTANT_InterfaceMethodref_info11符号引用接口中方法的符号引用
CONSTANT_NameAndType_info12符号引用字段或方法的部分符号引用


表1

1.CONSTANT_Utf8_info
表结构:
类??型项目数??目说明
u1tag1值为1
u2length1UTF-8缩略编码的字符串占用的字节数
u1byteslengthUTF-8缩略编码的字符串的字节值

相比于其它常量表,该表比较特殊的地方在于,源文件中几乎所有可见的字符串都存放在CONSTANT_Utf8_info中, 其他类型的常量池项只不过是对CONSTANT_Utf8_info的引用,并附增上一些特有的属性,比如是符号引用。这里有一个很有意思的地方是,这里使用的编码格式是 UTF-8缩略编码,很明显这是为了节省空间,但缩略编码与UTF-8编码的不同之在哪呢?从’u0001’到’u007f’之间的字符,缩略编码采用一个字节存储,从’u0080’到’u07ff’之间的字符采用两个字节存储,从’u0800’到’uffff’之间的字符按照普通的UTF-8编码格式三个字节来存储。关于UTf-8缩略编码,我有一个问题没想明白,比如’u0707’这个数据,读取的时候可以理解为一个两字节的字符’u0707’,也可理解两个一字节的字符’u0007’,’u0007’。这是不是有其它辅助的解决办法,还是我哪里思考错误缺漏了?
2.CONSTANT_Integer_info
表结构:
类??型项目数??目说明
u1tag1值为3
u4bytes1整型常量值

不用多说了,就是存储四个字节长度的整型常量值
3.CONSTANT_Float_info
表结构:
类??型项目数??目说明
u1tag1值为4
u4bytes1单精度浮点型常量值

4.CONSTANT_Long_info
表结构:
类??型项目数??目说明
u1tag1值为5
u4high_bytes1长整型的高四位值
u4low_bytes1长整型的低四位值

类文件结构中基本的长度最长也只有u4(四个字节),所以对于8个字节长的长整型来说,必须要拆成两个u4的类型来存储,下面的CONSTANT_Double_info类似。长整型的高四位其实在低位,长整型的低四位其实在高位,但是我们连着8个字节读取的时候就是一个完整的long类型数据,所以这是基于这样读取方便设计的吗?
5.CONSTANT_Double_info
表结构:
类??型项目数??目说明
u1tag1值为6
u4high_bytes1双精度浮点的高四位值
u4low_bytes1双精度浮点的低四位值

6.CONSTANT_Class_info
表结构:
类??型项目数??目说明
u1tag1值为7
u2name_index1存储constant_pool中的索引值,CONSTANT_Utf8_info类型。

就像在CONSTANT_Utf8_info表结构一节讲的,CONSTANT_Class_info表并不是真的存储数据,而只是存储了一个CONSTANT_Utf8_info常量的索引值,CONSTANT_Class_info结构更重要的作用是,这个常量值经过CONSTANT_Class_info表一包装它就是用于表述类或接口的符号引用。
7.CONSTANT_String_info
表结构:
类??型项目数??目说明
u1tag1值为8
u2string_index1存储constant_pool中的索引值,CONSTANT_Utf8_info类型。

可能这个类型包装出来的字符串才代表是我们在代码中真正写的字符串常量值吧。
8.CONSTANT_Fieldref_info
表结构:
类??型项目数??目说明
u1tag1值为9
u2class_index1存储constant_pool中的索引值,CONSTANT_Class_info类型。记录定义该字段的类或接口。
u2name_and_type_index1constant_pool中的索引值,CONSTANT_NameAndType_info类型。指定类或接口中的字段名(name)和字段描述符(descriptor)。

这个表类型里面又包含了两个常量表的索引,最所以采用索引的方式而不是把表作为自己表结构的一部分是为了节约空间吗?
9.CONSTANT_Methodref_info
表结构:
类??型项目数??目说明
u1tag1值为10
u2class_index1存储constant_pool中的索引值,CONSTANT_Class_info类型。记录定义该字段的类或接口。
u2name_and_type_index1constant_pool中的索引值,CONSTANT_NameAndType_info类型。指定类或接口中的字段名(name)和字段描述符(descriptor)。

10.CONSTANT_InterfaceMethodref_info
表结构:
类??型项目数??目说明
u1tag1值为11
u2class_index1存储constant_pool中的索引值,CONSTANT_Class_info类型。记录定义该字段的类或接口。
u2name_and_type_index1constant_pool中的索引值,CONSTANT_NameAndType_info类型。指定类或接口中的字段名(name)和字段描述符(descriptor)。

11.CONSTANT_NameAndType_info
表结构:
类??型项目数??目说明
u1tag1值为12
u2name_index1constant_pool中的索引,CONSTANT_Utf8_info类型。指定字段或方法的名称
u2name_index1constant_pool中的索引,CONSTANT_Utf8_info类型。指定字段或方法的描述符

CONSTANT_Fieldref_info,CONSTANT_Methodref_info,CONSTANT_InterfaceMethodref_info都引用了该表结构,就是因为需要名称和描述符两个字符串。

参考:


https://www.cnblogs.com/jiangyang/p/6526973.htmlhttps://blog.csdn.net/csdn1017355712/article/details/79788456



友情链接: