常量的类型有12种
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符号引用字段或方法的部分符号引用
这些常量一般都是相互引用的,是一个常量引用了另一个常量,其中String等基本类型大家都很好理解,我们也不多做讨论,下面我们挑选几个相对来说不是很好理解的来说说,按照顺序来看
UTF8常量
看到UTF8我们就会想到,这是一种字符编码格式,可以存储多个字节长度的字符串值,例如可以存储方法名等很长的一个字符串。
UTF8类型一般是由前两个字节来表示后面所存储的字符串总字节数,例如 01004c,其中,01表示UTF8类型常量,004c表示后面的字节数,004c = 4*16+12 = 76,也就是后面有76字节数长度。大概结构如下,可以分成三部分理解,一是常量是什么格式,第二个是常量有多少字节,第三个是常量的实际内容。
[01 | byte byte |byte byte.....]
Fieldref、Methodref常量
这两个很明显是为了描述Class中的属性项还有方法的,那么如何去表示Class中的一个属性和方法呢?我们首先要分析一下这两个常量中都有哪些信息。
0900110010这个常量就是Fieldref常量,09是标识,0011表示该Fieldref是哪个类中的Field,存储的是第几个常量的位置,0010表示该常量名和类型也就是NameAndType类型常量的索引。Methodref与其类似,第一个自己表示的是常量类型10也就是0a。后面两个字节表示是该方法属于哪个类,后面表示的也是NameAndType类型常量的索引。
[09 | byte byte |byte byte|] [0a | byte byte |byte byte]
Class常量
Class常量表示的事该类的名称,它会指向另外一个UTF8类型的常量,该常量存储具体的该类的名称。例如070013,07表示的是Class类型常量,0013指向的是第19个常量,而当我们找到第19个常量,可以发现它是一个UTF8常量,并且可以发现它存储的就是一个类的名称。
[07 | byte byte]
NameAndType常量类型
该常量是为了表示Methodref和Fieldref的名称和类型描述做的进一步说明而存在的,名称一般是由UTF8常量来表,类型的描述也是由UTF8来表示,所以这个类型是由一个字节的类型标识加上两个字节的UFT8位置索引构成的。例如0c00070008,0007指向第七个常量,也就是Fieldref类型常量或者Methodref,0008指向的第八个常量则是Methodref的返回类型或者是Fieldref的参数类型。
[0c | byte byte |byte byte]
大家好,我是一个程序员,对,就是你们认为的那种程序员,平时会写点文章,一个是可以再这个过程自己也学习并能巩固,第二也是可以跟大家分享一下,各位同是猿类的可以帮忙点关注,点点赞来支持一下你们搬砖路上的小伙伴,谢谢啦。