Java字符串常量池的作用是什么
这篇文章将为大家详细讲解有关Java字符串常量池的作用是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
为什么会有常量池的概念?
不知道小伙伴们是否有思考过这个问题? 没有思考也无所谓,小编在这里类比一下,大家就会清晰了。什么是池? 我们听的最多的池,应该是数据库连接池. 为什么会有数据库连接池,其实就是为了节省资源,提高性能,防止重复创建连接,避免占用内存和网络资源。
常量池其实就是跟数据库连接池的目的都是一样的。那么他是如何实现的呢? 因为常量池是JVM的概念,源码我们也不好看,所以我们还以连接池来类比。
池化的目标就是缓存和管理
稍微提一点池化的概念,其实就是对资源做一个包装,在包装层来加一些对这个资源的属性信息,比如使用次数,最后操作时间,最长生命周期一样。然后通过后台线程对资源包装层的扫描,来对真实资源的做一个管理。Google的Guava的Cache就是这么做的,我们自己也可以利用 common-pool2 工具包自己来做,或者说池化。
Java字符串常量池
在 JDK 1.7 之前,HotSpot 虚拟机中的字符串常量池都在方法区中,用永生代实现。JDK 1.7 及以后的版本,字符串常量池移到了堆里。
JDK 1.6 的 String.intern 方法会将首次遇到的 String 对象复制到永久代,并返回这个对象的引用。
JDK 1.7 的 String.intern 方法不再复制,而是记录首次出现的 String 对象的引用。
以下用 JDK 1.8 实验探究字符串常量池。
// test1String s1 = "red";String s2 = "red";System.out.println(s1 == s2); // true// test2String s3 = new String("red");String s4 = new String("red");System.out.println(s3 == s4); // false// test3System.out.println(s1 == s3); // false// test4System.out.println(s3.intern() == s1); // trueSystem.out.println(s3.intern() == s3); // falseSystem.out.println(s3.intern() == s4); // false// test5String s5 = new String("thunder");String s6 = s5.intern();String s7 = "thunder";System.out.println(s5 == s6); // falseSystem.out.println(s6 == s7); // true// test6String s8 = new String("1") + new String("1");// String s8 = new StringBuilder().append().toString()String s9 = s8.intern();String s10 = "11";System.out.println(s8 == s9); // trueSystem.out.println(s9 == s10); // true
常量池可以看作是一个集合,没有重复的元素。用双引号创建的对象直接放到常量池,new 一定会在堆中创建一个新的对象,如果常量池没有值相同的对象那么会在常量池也创建一个对象。intern 的作用是判断常量池是否包含值相同的字符串,是则返回这个字符串对象的引用,否则将当前实例的引用放到常量池并返回当前实例的引用。
另外,字符串的拼接实际上是用了 StringBuilder,所以字符串 s8 的创建会伴随以下对象的创建:
堆中两个不同的 String 对象 1
字符串常量池中一个 String 对象 1
一个 StringBuilder 对象
堆中的 String 对象 11
由于 s8 的创建方式不是 new String 而是拼接,所以不会在常量池中创建值为“11”的对象,这也是 test5 和 test6 要对比的问题。
关于Java字符串常量池的作用是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341