WEB开发网
开发学院WEB开发Jsp java基础知识:KVM的常量池 阅读

java基础知识:KVM的常量池

 2008-01-05 08:25:19 来源:WEB开发网   
核心提示:在class文件中,“常量池”是最复杂也最值得关注的内容,java基础知识:KVM的常量池, java是一种动态连接的语言,常量池的作用非

在class文件中,“常量池”是最复杂也最值得关注的内容。

java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值还,还包含一些以文本形式出现的符号引用,比如:

类和接口的全限定名;

字段的名称和描述符;

方法和名称和描述符。

在C语言中,假如一个程序要调用其它库中的函数,在连接时,该函数在库中的位置(即相对于库文件开头的偏移量)会被写在程序中,在运行时,直接去这个地址调用函数;

而在Java语言中不是这样,一切都是动态的。编译时,假如发现对其它类方法的调用或者对其它类字段的引用的话,记录进class文件中的,只能是一个文本形式的符号引用,在连接过程中,虚拟机根据这个文本信息去查找对应的方法或字段。

所以,与Java语言中的所谓“常量”不同,class文件中的“常量”内容很非富,这些常量集中在class中的一个区域存放,一个紧接着一个,这里就称为“常量池”。

常量池由多条“常量池项”组成,每一个常量池项又由两部分组成,这里分别称为“常量池项头”和“常量池项体”。

常量池项头表明常量池项的类型,常量池项共分为11种类型,分别为:

常量池项类型

说明

CONSTANT_Utf8

1

UTF-8编码的Unicode字符串

CONSTANT_Integer

3

int型常量

CONSTANT_Float

4

Float型常量

CONSTANT_Long

5

Long型常量

CONSTANT_Double

6

double型常量

CONSTANT_Class

7

对一个class的符号引用

CONSTANT_String

8

String型常量

CONSTANT_Fieldref

9

对一个字段的符号引用

CONSTANT_Methodref

10

对一个类方法的符号引用

CONSTANT_InterfaceMedthodref

11

对一个接口方法的符号引用

CONSTANT_NameAndType

12

对名称和类型的符号引用

常量池项体中存放的就是对应的常量数据,比如各种数值型的常量或者字符串等等。

以下介绍kvm中的常量池是如何组织起来的。

 

数据结构:

在KVM的头文件kvm/vmcommon/h/pool.h中,有以下对常量池项类型的定义:

Word-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> #define CONSTANT_Utf8            1
#define CONSTANT_Integer          3
#define CONSTANT_Float           4
#define CONSTANT_Long            5
#define CONSTANT_Double           6
#define CONSTANT_Class           7
#define CONSTANT_String           8
#define CONSTANT_Fieldref          9
#define CONSTANT_Methodref         10
#define CONSTANT_InterfaceMethodref  11
#define CONSTANT_NameAndType      12 以及常量池项体结构的定义: union constantPoolEntryStrUCt {
  struct { 
    unsigned short classIndex;
    unsigned short nameTypeIndex;
  }        method; /* Also used by Fields */
  CLASS      clazz;
  INTERNED_STRING_INSTANCE String;
  cell      *cache;  /* Either clazz or String */
  cell      integer;
  long      length;
  NameTypeKey   nameTypeKey;
  NameKey     nameKey;
  UString     ustring;
};

class文件中,常量池项有很多种类,每一个常量池项的大小都不同,而对于常量池的使用又是如此之多,最好能够使用数组来索引,这样可以提高效率,所以KVM里使用union来代表一个常池项,union的每一项是常量池项的一种可能的数据类型,这样每一项都有了相同的大小,可以构造数组。

显然,这个数组就将是常量池的核心内容,那么这个数组放在哪里呢?就在下面这个结构中:


Tags:java 基础知识 KVM

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接