字符串常量池

举报
西魏陶渊明 发表于 2022/09/25 02:03:27 2022/09/25
【摘要】 真正的猛士,每天干一碗毒鸡汤! 问世间钱为何物,只叫人生死相许。!😄 本篇课程不来虚的,上来就是干活,现在发车。小编通过代码案例及比喻,带你一窥究竟。 # 为什么会有常量池的概念? 不知道小伙伴们是否有思考过这个问题? 没有思考也无所谓,小编在这里类比一下,大家就会清晰了。 什么是池? 我们听的最多的池...

真正的猛士,每天干一碗毒鸡汤!

问世间钱为何物,只叫人生死相许。!😄

本篇课程不来虚的,上来就是干活,现在发车。小编通过代码案例及比喻,带你一窥究竟。

# 为什么会有常量池的概念?

不知道小伙伴们是否有思考过这个问题? 没有思考也无所谓,小编在这里类比一下,大家就会清晰了。 什么是池? 我们听的最多的池,应该是数据库连接池. 为什么会有数据库连接池,其实就是为了节省资源,提高性能,防止重复创建连接,避免占用内存和网络资源。

常量池其实就是跟数据库连接池的目的都是一样的。那么他是如何实现的呢? 因为常量池是JVM的概念,源码我们也不好看,所以我们还以连接池来类比,请看下文。

# 池化的目标就是缓存和管理

稍微提一点池化的概念,其实就是对资源做一个包装,在包装层来加一些对这个资源的属性信息,比如使用次数,最后操作时间,最长生命周期一样。然后通过后台线程对资源包装层的扫描,来对真实资源的做一个管理。Google的Guava的Cache就是这么做的,我们自己也可以利用 common-pool2 工具包自己来做,或者说池化。

# JVM常量池就相当于一个缓存

常量就是不会改变的信息,那么既然是不会改变的信息,系统中只存在一份,就可以了。存在多份也是浪费内存资源。然而在Java中只要是new的信息都会在堆上开辟一个新的空间,为了解决这个问题,JVM中才出现了字符串常量池的概念。但是只有直接用""修饰的字符,才会被加入到常量池中,当再次用""创建的时候,会首先从常量池中去获取。


    
  1. String s1 = "1";
  2. String s2 = "1";
  3. //true
  4. System.out.print(s1==s2);
  5. String s3 = new String("1");
  6. String s4 = new String("1");
  7. //false
  8. System.out.print(s3==s4);
1 2 3 4 5 6 7 8

我们可以把常量池理解为一个Map<String,String>做的缓存容器。只不过这个缓存机制是有JVM使用C语言写的。我们看不到而已。

# String.intern()的使用

new 出来的 String 类型是否也能使用常量池呢? 当然可以,就是通过 intern 方法 这个方法的意思就是先到缓存中(也就是常量池中)查询当前对象是否存在,存在就返回常量池中地址,不存在就加入常量池。我们可以用一段伪代码来解释一波。


    
  1. //双引号直接放入常量池
  2. String s1 = "1";
  3. String s2 = new String("1");
  4. //false
  5. System.out.println(s1 == s2);
  6. //先到常量池中查询是否有”1“,存在就将常量池中对象返回,不存在就放到常量池中(此时常量池中存在s1)
  7. //于是就将s1的值重新复制给s3,所以s1 == s3
  8. String s3 = new String("1").intern();
  9. //true
  10. System.out.println(s1 == s3);
1 2 3 4 5 6 7 8 9 10

文章来源: springlearn.blog.csdn.net,作者:西魏陶渊明,版权归原作者所有,如需转载,请联系作者。

原文链接:springlearn.blog.csdn.net/article/details/125858135

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。