常量池、StringTable(字符串常量池池)和堆内存

StringTable 特性

  • 常量池中的字符串仅是符号,第一次用到时才变为对象

  • 利用串池的机制,来避免重复创建字符串对象

  • 字符串变量拼接的原理是 StringBuilder (1.8)

  • 字符串常量拼接的原理是编译期优化

  • 可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池

  • 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串池中的对象返回

  • 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回

一、串池StringTable和常量池的关系

常量池和串池的关系_敏叔V587的博客-CSDN博客_串池和常量池

二、字符串的拼接

在这里插入图片描述

上面的代码中s3==s4的返回结果是false,因为s4是通过底层的StringBUilder拼接成为的存在堆内存中的新对象,而s3是常量池的ab对象,两者并不相等

那如果有
String s5 = "a" + "b";
s5 == s3 ? ----> true
这个是为什么呢?
这是因为javac在编译期的优化,结果在编译期把‘a'+ 'b'确认为ab,所以s5会和常量池中的ab对象一样


在这里插入图片描述

三、 Intern

String s = s1.intern();

作用:把一个字符串对象尝试放入串池中,如果串池中有该对象则不会放入,如果没有则放入串池中,同时会返回串池中的字符串对象

观看下图:判断输出结果

在这里插入图片描述

String s = new String("a") + new String("b");

对于上面的这一行代码解释是这样子的

  • 首先,new String(“a”),一开始串池中没有a这个对象,会把a放入串池中,堆内存中也会放入a

  • 然后new String(“b”),会把对象b放入串池中,串池就会变成[“a”,“b”],堆内存中也会放入b

  • 并且a,b两个对象会通过底层的StringBuilder拼接成为一个新的对象s,注意 s=“ab”,由于这个对象s只是拼接出来的,不是new出来的,并不会放入到串池中

如果没有执行s.intern()的话,字符串常量池中只有a,b两个对象,而没有ab这个对象,此时

System.out.printnl(s == 'ab') //false, 
因为s是堆内存中的对象,ab是一个需要实例的对象,会放入常量池中,和s不是同一个对象

但是我们如果执行 s.intern()之后再比较,结果就会不一样了

String s2 = s.intern();

System.out.println(s2 == ‘ab’); //true

System.out.println(s == ‘ab’); //true

上面执行String s2 = s.intern();的时候,堆内存中的s这个对象会被放入常量池,所以对象ab会存在常量池中,并且s2是返回的放入后的常量池中ab这个对象,所以上面是相等的

如果事先定义好x = ‘ab’,会怎么样呢?如下图:

在这里插入图片描述

按照上面的分析,常量池是[“ab”,“a”,“b”],s=“ab”是堆中的对象,当执行

String s2 = s.intren()的时候,会尝试吧堆中的s对象放入常量池,但是常量池中已经有了ab这个对象,所以s='ab’这个对象并不会放入常量池中,但是s2会被返回来的常量池中的ab对象赋值,需要注意的是,这个时候,s还是堆中的ab这个对象,s2是等于常量池中的ab这个对象,所以这个时候

s2==‘ab’ //true

s== ‘ab’ //FALSE
需要注意的是,这个时候,s还是堆中的ab这个对象,s2是等于常量池中的ab这个对象,所以这个时候

s2==‘ab’ //true

s== ‘ab’ //FALSE

四、StringTable调优

https://blog.csdn.net/weixin_44741023/article/details/122694046?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165992931516782395369302%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165992931516782395369302&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-122694046-null-null.142v39pc_rank_34_1,185v2control&utm_term=StringTable%E8%B0%83%E4%BC%98&spm=1018.2226.3001.4187

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值