JVM-字符串常量池
JVM——字符串常量池StringTable
String
- JDK8及以前:final char[] value
- JDK9及以后:final byte[] value
因为大多数字符串只包括拉丁字符,只需1字节的存储空间,而char占2字节,若使用char[],会有将近一半空间被浪费
String的不可变性
- String类型声明为final,说明String不可被继承
- String内部存储内容的也是一个final数组,说明引用地址不变
字符串的拼接操作
- 常量 + 常量:拼接结果在常量池(编译期优化)
- 常量 + 变量 / 变量 + 常量 / 变量 + 变量:拼接结果在堆中(底层创建一个StringBuilder对象用于拼接)
intern方法
native方法,底层由C语言实现。判断字符串常量池中是否存在对应的值,若存在,则直接返回该字符串在常量池中的地址;若不存在,先在字符串常量池中加载一份,然后返回其在字符串常量池中的地址
对于程序中存在很多重复字符串时,使用intern方法可以节省很大的内存空间
示例
1 |
|
- 在JDK6时,由于字符串常量池中没有“ab”,执行s1.intern()会在常量池中创建一个“ab”,s2会指向这个常量池中的“ab”;
- 而在JDK7/8时,由于堆中已经有s1 = new String(“ab”)了,为了节省空间,直接将堆中s1的引用地址存储在字符串常量池中(即“ab” == s1),即s2指向的是s1在堆中的地址
因此在JDK6中:s1 == “ab”为false,s2 == “ab”为true;
而在JDK7/8中:s1 == “ab” 与 s2 == “ab”均为true,因为s2和“ab”指向的都是s1
JVM-字符串常量池
http://example.com/2025/05/16/JVM-字符串常量池/