jdm常量池

常量池(静态常量池):编译时每个class文件中都存在常量池,class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant pool table),用于存放编译期生成的各种字面量和符号引用。

运行时常量池:运行时常量池这部分内容,在类初始化进入运行时常量池中存放

字符串常量池:只会存储一份,被所有的类共享。创建字符串之前检查常量池中是否存在,如果存在则获取其引用,如果不存在则创建并存入,返回新对象引用。

常量池的演变
1.7之前
jdm常量池
1.7
jdm常量池
1.8
jdm常量池
方法区 是一种理论概念,hotsport在1.8之前用 永久代来实现,在1.8用元空间实现。

个人理解 - 个人理解不用说
静态变量存在那 statics
元空间,方法区 引用
实际对象在 元空间

常量存在哪 final
元空间,方法区 引用
实际对象在 元空间

字符串在哪 string
引用在字符长常量池
对象在堆中
jdm常量池
首先根据 final 修饰的常量会在编译期放到常量池的原则,n2会在编译期间放到常量池中。

s 变量所对应的”20190522”字符串会放入到字符串常量池中,并对外提供一个引用返回给 s 变量。

拼接字符串 s1,由于 n1 对应的数据没有放入常量池中,所以 s1 暂时无法拼接,需要等程序加载运行时才能确定 s1 对应的值。

拼接字符串 s2,由于 n2 已经存在于常量池,所以可以直接与”0522”拼接,拼接出的结果是”20190522”,这时系统会查看字符串常量池,发现已经存在字符串20190522,所以直接返回20190522的引用。
所以 s2 和 s 指向的是同一个引用,这个引用指向的是字符串常量池中的20190522。
而 n1 会在程序执行时,才有具体的指向。

当拼接 s1 的时候,会创建一个新的 String类型对象,也就是说字符串常量池中的 20190522 会对外提供一个新的引用。所以当 s1 与 s 用 “==” 判断时, 由于对应的引用不同, 会返回 false。而 s2 和 s 指向同一个引用,返回true。

上一篇:【贪玩巴斯】C++ tips——知识点: substr()截取函数 & replace()替换函数 & find查找函数 & 类似JAVA中substring()函数


下一篇:正则匹配问题