3、接下来就是constant_pool
前面讲过,常量池里存放的是字面常量和符号引用。
1、字面常量
字面常量分别包含String,Integer,Float,Long,Double这几个类型,这些字段都是以二进制的方式存储的,所以存储的时候,只要指定类型、长度和对应的值即可。这样的话,那这些基本的常量就可以采用如下的结构来表示:
- CONSTANT_XXX{
- type;//该常量的类型
- length;//该常量的长度,以字节为单位
- byte[];//该常量的二进制表示,包含length个字节
- }
不过对于Integer、Float、Long和Double这些常量的长度是固定不变的,所以可以省去以节省空间;但是字符串常量的长度是不能省的。
2、符号引用
符号引用包含三种特殊的字符串,它们分别是:
1、全局限定名 当一个常量表示类或者接口的时候,需要指定类的全局限定名,在class文件中,全局限定名的点用斜杠来代替,例如java.lang.Object的全局限定名为java/lang/Object
2、简单名称 类的字段名或者方法名以简单名称的方式存在常量池里,例如上面Hello.test字段在class文件里会存有形如“test”的简单名称。
3、描述符 除了成员变量的名称和方法,class文件里还要存储对应的描述符。描述符在class文件里以一种简化的方式表示,这样就可以减少class文件的大小。
成员变量的描述符和方法的修饰符可以使用下面的语法来表示:
- FieldDescriptor:
- FieldType
- ComponentType:
- FieldType
- FieldType:
- BaseType
- ObjectType
- ArrayType
- BaseType:
- B
- C
- D
- F
- I
- J
- S
- Z
- ObjectType:
- L Classname ;
- ArrayType:
- [ComponentType
- MethodDescriptor:
- ( ParameterDescriptor* ) ReturnDescriptor
- ParameterDescriptor:
- FieldType
- ReturnDescriptor:
- FieldType
- VoidDescriptor
- VoidDescriptor:
- V
简单来说,对于成员变量而言,它的描述符是它的类型,类型又分为:BasicType,ObjectType和ArrayType。
- BasicType指的是byte,char,double,float,int,long,short,boolean这几种基本类型,它们分别用B、C、D、F、I、L、S、Z来表示。
- ObjectType指的是对象类型,也就是说该成员变量的类型是一个Java类,那么这种类型就用L加上Classname表示。例如一个类型为java.lang.String的变量,它的描述符为Ljava/lang/String。
- ArrayType指的是列表类型,也就是说这个成员变量是个数组。对于数组类型,每一个维度用一个前置的“[”来描述。例如一个定义为"java.lang.String[][]"的变量的描述符为[[java/lang/String;对于一个定义为“int[]”的变量,它的描述符表示为“[I”。
对于方法而言,它的描述符是先参数列表,后返回值的方式组成。参数列表按照声明的顺序排列,每个参数的格式和成员变量的格式一样。所有的参数放在一个括号里面和返回值进行分隔。返回值的格式也和成员变量的格式一样,不过返回值多了一个void类型,用“V”来表示。
例如,对于void test()方法,它的描述符表示为“()V”,而对于java.lang.String test(int[],int index)方法,它的描述符表示为“([II)Ljava/lang/String”。
这些特殊的字符串在常量池里是采取引用的方式来表示的,它们有如下的结构:
- CONSTANT_XXX{
- type;//字符串的类型
- index;//对应的值的引用
- }
3、字符串的存储方式
在class文件里,字符串也是采用引用的方式进行存储的,它的引用指向该字符串对应的UTF-8的一个变体的表示。
- CONSTANT_XXX{
- type;//字符串的类型
- index;//对应的值的引用
- }
对应的UTF-8表示的结构
- CONSTANT_UTF8{
- type;
- length;
- value[];
- }
4、常量的基本格式
由上面的分析可以知道,常量的结构都是以常量的类型开始,然后才是具体的数据。这样的话,常量池里的变量都是如下的结构:
- cp_info {
- u1 tag;
- u1 info[];
- }
其中的tag就是常量对应的类型,主要有以下几个值:
后面的info[]字段,代表具体结构的数据,需要按照对应的结构来进行分析。
阅读(3114) | 评论(0) | 转发(1) |