JVM 字符串常量池

JDK版本:8

"常量池"有哪些
  • class文件中的常量池
  • 运行时常量池
  • 字符串常量池

class文件的常量池

存储在磁盘上,class文件的Constant Pool,通过javap -verbose可以查看,静态的

运行时常量池

存储在instanceKlass实例(元空间),通过HSDB可以查看,动态的

字符串常量池(本文重点)

存储在虚拟机堆,StringTable(c++类,底层是HashTable),动态的

字符串常量池存储结构

在这里插入图片描述

字符串常量池底层是一个StringTable类型对象,StringTable是HashTable的子类,所以把它看作HashTable就很好理解了。
HashTable底层数据结构是数组+链表,数组的每个位置存放HashtableEntry链表,每个HashtableEntry对象存储key、value键值对,HashtableEntry存放在数组哪个位置由HashtableEntry的key值与数组长度取余来决定。
HashtableEntry的key是根据字符串内容+字符串内容的长度计算出来的hash值,value指向String对象。
String对象指向char数组,char数组保存实际数据。

String a = “aaa”;存储结构

需要明确的是:由于"aaa"是写死的,所以会进入字符串常量池。上文介绍字符串常量池存储结构时用的就是这个例子,所以不在赘述。
总结String a = “aaa”;这行代码会生成一个String对象,一个char数组。
在这里插入图片描述

String b = new String(“bbb”);存储结构

首先由于"bbb"是写死的,所以会进入字符串常量池。
String b = new String(“bbb”);这行代码会生成两个String对象,一个char数组,因为显示声明了一个String对象,所以比上个案例多一个String对象,两个String对象指向同一个char数组。
在这里插入图片描述
在这里插入图片描述

String c = “aaa” + “bbb”;存储结构

两个写死的字符串拼接,在编译期间就会进行优化,变成String c = “aaabbb”;,等同于第一个案例,会生成一个String对象,一个char数组。
在这里插入图片描述

String d = “aaa” + new String(“bbb”);存储结构

"aaa"和"bbb"是写死的会进入字符串常量池,"aaabbb"是计算出来的,所以不会进入字符串常量池。
这里需要注意的是new String(“bbb”),如果直接声明一个引用指向他,那会生成一个新的String对象;如果只是用于计算,则不会。所以String d = “aaa” + new String(“bbb”);这行代码会生成三个String对象,三个char数组。
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值