常量池 字符串常量池 class常量池 运行时常量池详解

本文先简述下常量池随JDK版本更替而产生的变化,后介绍三种常量池的区别,可按需观看.

JDK版本迭代造成的变化

首先,众所周知,“常量池属于方法区的一部分”,这句话对于JDK6之前可能完全准确,但在JDK7之后就会有人有不同的理解了.
这里以Hotspot虚拟机来进行说明.
JDK6及其之前,方法区通过永久代进行实现,而常量池属于方法区的一部分也存在于永久代中,此时方法区甚至可以等同于永久代,因此说常量池是方法区的一部分是完全没有问题的.
而在JDK7中,Hotspot将原本存储于永久代中的字符串常量池和静态变量移入堆中存储.但方法区中的其余内容依旧存储于永久代中(ps:永久代也是堆内的一片连续空间,因此此时二者其实也还都在堆中)
JDK8彻底废除永久代,改用元空间实现方法区,并将方法区中其余内容全部移入元空间(元空间靠堆外内存实现),也就是说,此时常量池和静态变量存储于堆中,而方法区其余内容则是存储于堆外内存
故在JDK8中,方法区其实已经被拆分了,常量池逻辑上属于方法区,而实际存储则如上所述.

三大常量池的区别

  1. class常量池:存储类的信息与字面量(和字面量引用区分开,字面量是int a = 1,String str = “abc”里的1和”abc”)
  2. 运行时常量池:当类加载到内存后(详见类加载过程),class常量池中的内容就会全部存放到运行时常量池(因此运行时常量池也是一个类一个),但运行时常量池中的内容可以在运行时动态添加(最明显的就是字符串)
  3. 字符串常量池:存放字符串的引用,实际的值存储在运行时常量池中.
    因此,找字符串就先在字符串常量池中找,找不到再新建然后添加引用到字符串常量池中,而找其余字面量则是去对应类的运行时常量池中找,基础数据类型就直接比较,否则就比较地址.

证明如下图
在这里插入图片描述
运行结果ture,false.
因为a,b和A.a,A.b属于不同类,也存储于不同的运行时常量池中,故其地址也不同,但根据上述比较关系,a和A.a直接比较值故返回true,而b和A.b则比较地址,二者存储的运行时常量池都不同,地址一定不同,故返回false.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值