有什么作用
主要用来存放两大类常量:字面量 和 符号引用。
字面量包括以下几种:
文本字符串
8大基本数据类型
final修饰的常量
符号引用包含以下几种:
类和接口的全限定名
子段的名称和描述符
方法的名称和描述符
基本组成是什么
常量池的每一个常量都是一个表结构,由以下14个基本表结构组成
八大基本数据类型中 boolean, byte, short, int, char 都对应的是 CONSTANT_Integer_info 字段
上面的每一个类型都是一个表结构,至少包含两个字段,比如 CONSTANT_Class_info结构如下:
| 类型 | 名称 | 数量 |
|---|---|---|
| u1 | tag | 1 |
| u2 | name_index | 1 |
tag就是CONSTANT_Class_info对应的标志位7
name_index是一个索引值,因为这里需要的是类或者接口的全限定名,所以会指向一个CONSTANT_Utf8_info结构
变量,方法名最长多长,为什么?
最长65535,即64KB,因为变量,方法名都是在CONSTANT_Utf8_info中存放,该结构有三个字段:
| 类型 | 名称 | 数量 |
|---|---|---|
| u1 | tag | 1 |
| u2 | length | 1 |
| u1 | bytes | length |
lengh表示的是名称的长度,u2表示的是两个字节的无符号整数,最大值为65535.
代码中怎么体现出来
写一个简单的例子
/**
* FileName : TestConstantPool.java
* Created by zongpengq on 9/21/2018.
*/
public class TestConstantPool {
static int intData;
static boolean ifData;
static char charData;
public static void main(String[] args) {
intData = 12;
ifData = false;
charData = 'a';
}
}
用 javac TestConstantPool.java 得到字节码文件 TestConstantPool.class,再通过 javap -v TestConstantPool.class 可以看到代码对应的常量池部分
反编译之后发现有这段代码编译之后常量池中放有26个常量类型,简单取其中#1解释一下
#1常量类型是 Methodref表示是一个类方法索引常量,用来描述Object的<init>方法,由类索引信息#6 和 方法索引信息 #21组成
#6是Class类型,指向Obejct类,所以的全限定名又存放到 #26 Utf8类型中
#21是NameAndType类型用来描述方法#13 和方法描述符信息#14
#14用()V表示函数返回值为void