jvm在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,运行时常量池也是每个类都有一个。在上面我也说了,class常量池中存的是字面量和符号引用,也就是说他们存的并不是对象的实例,而是对象的符号引用值。而经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是我们上面所说的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。
所以简单来说,运行时常量池就是用来存放class常量池中的内容的。
总结我们将三者进行一个比较
以一道测试题结束 // 环境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虚拟机规范》