从字符串到常量池,一文看懂String类设计 (6)

jvm在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,运行时常量池也是每个类都有一个。在上面我也说了,class常量池中存的是字面量和符号引用,也就是说他们存的并不是对象的实例,而是对象的符号引用值。而经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是我们上面所说的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的

所以简单来说,运行时常量池就是用来存放class常量池中的内容的。

总结

我们将三者进行一个比较

image-20200617025721586

以一道测试题结束 // 环境1.7及以上 public class Clazz { public static void main(String[] args) { String s1 = new StringBuilder().append("ja").append("va1").toString(); String s2 = s1.intern(); System.out.println(s1==s2); String s5 = "dmz"; String s3 = new StringBuilder().append("d").append("mz").toString(); String s4 = s3.intern(); System.out.println(s3 == s4); String s7 = new StringBuilder().append("s").append("pring").toString(); String s8 = s7.intern(); String s6 = "spring"; System.out.println(s7 == s8); } }

答案是true,false,true。大家可以仔细思考为什么,如有疑惑可以给我留言,或者进群交流!

如果本文对你有帮助的话,记得点个赞吧!也欢迎关注我的公众号,微信搜索:程序员DMZ,或者扫描下方二维码,跟着我一起认认真真学Java,踏踏实实做一个coder。

公众号

我叫DMZ,一个在学习路上匍匐前行的小菜鸟!

参考文章:

R大博文:请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧

R大知乎回答:JVM 常量池中存储的是对象还是引用呢?

Java中几种常量池的区分

方法区,永久代和元空间

美团:深入解析String#intern

参考书籍:

《深入理解Java虚拟机》第二版

《深入理解Java虚拟机》第三版

《Java虚拟机规范》

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypdgs.html