在.java文件,讲过javac编译后产生的 .class文件中,头4个字节表示的是魔数,接着魔数后面的第5,6个字节存储的是次版本号,第7,8个字节存储的主板本号.那么再接下来的就是表示常量池入口了.
常量池
可以理解为class文件之中的资源仓库,它是class文件结构中与其他项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一,同时它还是class文件中第一个出现表类型的数据项目.由于常量池的数量是不固定的,所以在常量池入口需要放置一项u2(即2个字节)类型的数据,代表常量池容量计数值(constant-pool-count)(从1开始,将0表示不引用任何常量).
常量池中主要存放两大类常量:字面量(Literal)和符号引用(Synbolic Reference).
- 字面量:比较接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值.
- 符号引用:包括如下三类常量:
- 类和接口的全限定名(Fully Qualified Name)
- 字段的名称和描述符(Descriptor)
- 方法的名称和描述符
常量池中每一项常量都是一个表(14种表).
类型 | 标志 | 描述 |
CONSTANT_utf8_info | 1 | UTF-8编码的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮点型字面量 |
CONSTANT_Long_info | 5 | 长整型字面量 |
CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
CONSTANT_Class_info | 7 | 类或接口的符号引用 |
CONSTANT_String_info | 8 | 字符串类型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
CONSTANT_Methodref_info | 10 | 类中方法的符号引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符号引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的符号引用 |
CONSTANT_MothodType_info | 16 | 标志方法类型 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |
注意:在这14种表有一个共同的特点,就是开始的第一位是一个u1类型的标志位(tag,就是上表中的标志这一列),代表当前这个常量属于哪种常量类型.下面分析实例的时候会用到.
由于class文件中方法,字段等都需要引用CONSTANT_utf8_info类型常量来描述名称,所以CONSTANT_utf8_info类型常量的最大长度也就是Java中方法,字段名的最大长度(Java程序中如果定义了超过64KB英文字符的变量或方法名,将无法编译).