一个常量池中的CONSTANT_Float_info数据项, 可以看做是CONSTANT_Float类型的一个实例。 它存储的是源文件中出现的float型数据的值。 同样, 作为常量池中的一种数据类型,
它的第一个字节也是一个tag值, 它的tag值为4, 也就是说, 当虚拟机读到一个tag值为4的数据项时, 就知道这个数据项是一个CONSTANT_Float_info, 并且知道它存储的是float型数值。 紧挨着tag的下面4个字节叫做bytes, 就是float型的数值。
它的内存布局如下:
举例说明, 如果源文件中的一句代码使用了一个float值, 如下所示:
那么在这个类的常量池中就会有一个CONSTANT_Float_info与之相对应, 这个CONSTANT_Float_info的形式如下: 代码反编译结果如下:
(5)CONSTANT_Long_info一个常量池中的CONSTANT_Long_info数据项, 可以看做是CONSTANT_Long类型的一个实例。 它存储的是源文件中出现的long型数据的值。
同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值, 它的tag值为5, 也就是说, 当虚拟机读到一个tag值为5的数据项时, 就知道这个数据项是一个CONSTANT_Long_info, 并且知道它存储的是long型数值。
紧挨着tag的下面8个字节叫做bytes, 就是long型的数值。 它的内存布局如下:
举例说明, 如果源文件中的一句代码使用了一个long型的数值, 如下所示:
那么在这个类的常量池中就会有一个CONSTANT_Long_info与之相对应, 这个CONSTANT_Long_info的形式如下:
代码反编译结果为:
(6)CONSTANT_Double_info一个常量池中的CONSTANT_Double_info数据项, 可以看做是CONSTANT_Double类型的一个实例。 它存储的是源文件中出现的double型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值,
它的tag值为6, 也就是说, 当虚拟机读到一个tag值为6的数据项时, 就知道这个数据项是一个CONSTANT_Double_info, 并且知道它存储的是double型数值。 紧挨着tag的下面8个字节叫做bytes, 就是double型的数值。
它的内存布局如下:
![]() 举例说明, 如果源文件中的一句代码使用了一个double型的数值, 如下所示:
那么在这个类的常量池中就会有一个CONSTANT_Double_info与之相对应, 这个CONSTANT_Double_info的形式如下:
![]() 代码反编译结果为:
(7) CONSTANT_String_info在常量池中, 一个CONSTANT_String_info数据项, 是CONSTANT_String类型的一个实例。 它的作用是存储文字字符串, 可以把他看做是一个存在于class文件中的字符串对象。 同样, 它的第一个字节是tag值, 值为8 , 也就是说, 虚拟机访问一个数据项时, 判断tag值为8 , 就说明访问的数据项是一个CONSTANT_String_info
。 紧挨着tag的后两个字节是一个叫做string_index的常量池引用, 它指向一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info存放的才是字符串的字面量。 它的内存布局如下:
![]() 举例说明, 如果源文件中的一句代码使用了一个字符串常量, 如下所示:
那么在这个类的常量池中就会有一个CONSTANT_String_info与之相对应, 反编译结果如下:
其中printString方法中索引为3的字节码指令ldc引用常量池中的第21项, 第21项是一个CONSTANT_String_info, 这个位于第21项的CONSTANT_String_info又引用了常量池的第22项, 第22项是一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的字符串是 abcdef 。 引用关系的内存布局如下: ![]() 总结本文就到此为止。 最后总结一下, 本文主要讲解了常量池中的五中数据项, 分别为CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info, CONSTANT_Double_info
和CONSTANT_String_info 。 这几种常量池数据项都是直接存储的常量值,而不是符号引用。 这里又一次出现了符号引用的概念, 这个概念将会在下一篇博客中详细讲解, 因为下一篇博客要介绍的剩下的四种常量池数据项, 都是符号引用, 这四种表示符号引用的数据项又会直接或间接引用上篇文章中介绍的CONSTANT_NameAndType_info和CONSTANT_Utf8_info,
所以说CONSTANT_NameAndType_info是符号引用的一部分。
从本文中我们还可以知道。
虽然说CONSTANT_String_info是直接存储值的数据项, 但是CONSTANT_String_info有点特别, 因为它不是直接存储字符串, 而是引用了一个CONSTANT_Utf8_info,
这个被引用的CONSTANT_Utf8_info中存储了字符串。
最后, 列出下一篇博文要介绍的剩下的四种常量池数据项:
更多关于深入理解Java的文章, 请关注我的专栏 : http://blog.csdn.net/column/details/zhangjg-java-blog.html 更多关于Java和Android等其他技术的文章, 请关注我的博客: http://blog.csdn.net/zhangjg_blog |
|