java class 常量池有什么用,Java Class文件常量池

Class文件的存在使得不同语言编写的程序都可以运行在Java虚拟机上,只需要这些语言经过编译器编译后的Class文件符合Java虚拟机定义的规范,Java虚拟机就可以加载执行这些Class文件。如下图所示:

d2ae04d82426bc465a2dc00e762eba95.png

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,当遇到需要占用8个字节以上空间的数据是,则按照大端序的方式分割成若干个8位字节进行存储。

Class文件中只存在两种数据类型:

无符号数

无符号数属于基本数据类型,以u1、u2、u4、u8分别表示1个、2个、4个和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成的字符串值。

表是由无符号数和其他表组成的数据结构,所有的表都以_info结尾。

当在描述一个可变长度的类型数据时,通常会采用一个容量计数器和若干个数据项的格式。

cf0bf4d29c55725ccca6365c1c1edce4.png

public class ClassTest {private int m;private int inc() {return m + 1;}}

下面我们会通过上面这段代码来分析Class文件的内容。

1e4c0759b21780c0ee7a4f51698ee5b5.png

上面这张图是经过编译后的Class文件中的内容

魔数(magic)与版本号

Class文件开头固定的4个字节为魔数,唯一作用就是用来确定这个文件是否是一个能被虚拟机接收的class文件。Java的魔数固定为0xCAFEBABE,接下去的两个字节代表次要版本号,再下去的两个字节是主版本号,主版本号为0x0034(十进制是52,也就是JDK1.8),高版本的JDK能够运行以前版本的Class文件,但是不能运行以后版本的Class文件,通俗一点将就是向下兼容。

常量池

走过了魔数和版本,接下去是Class文件中最关键的部分常量池,常量池由一个计数池和具体的常量项来组成,在我们代码中常量池数量为0x0013(十进制是19),关于常量池的计数池有一个比较特殊的地方就是他是从1开始计数的,也就是说如果我们计数池的值是19,实际上是只有18个常量项。

常量池中主要存放两大类常量:

字面量

符号引用

字面量主要指的是文本字符串、声明为final的常量值等

符号引用主要包含三类常量:

类和接口的全限定名

字段的名称和描述符

方法的名称和描述符

Java代码在编译的时候不存在连接时,也就是Class文件中不会保存各个方法、字段的最终内存布局信息,这些字段、方法的符号引用如果在运行期不进行转换则得不到真正的内存入口地址,所以在虚拟机运行时,需要从常量池获得对应的符号引用,在类创建和运行时解析翻译到具体的内存地址中。

目前常量池中主要有以下表项:

6d5d525d373b59e432b5279613299d2b.png

这些表都会有一个固定的字段也就是开始的第一个字节都是一个标志位代表相应的类型,如上图。

大家可以通过javap -verbose xxx.class列出文件字节码的内容

09d27de05432a2ff5092d44d8a9e4530.png

通过比较javap -verbose常量池的项的索引和我们class文件二进制的表示可以发现是一一对应的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值