一. 特点
1. 常量池中的字符串仅是符号,第一次用到时才变为对象
2. 利用串池的机制,来避免重复创建字符串对象
3. 字符串变量拼接的原理是 StringBuilder(1.8),StringBuilder的toString()方法实际上是new出来的String
4. 字符串常量拼接的原理是编译期优化,"a"+"b"就当成"ab"创建
String s1="a"; String s2="b"; String s3="ab"; String s4=s1+s2; String s5="a"+"b"; System.out.println(s3==s4);//false StringBuilder System.out.println(s3==s5);//true 编译时优化
5. 可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池 1.8
// ["ab", "a", "b"] public static void main(String[] args) { String s = new String("a") + new String("b");//此时串池只有"a","b" // 堆 new String("a") new String("b") new String("ab") String s2 = s.intern(); // 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池(1.6是复制一份), 会把串池中的对象返回 String s3 = "ab"; System.out.println( s2 == s3);//true System.out.println( s == s3 );//true }
二. 位置
1.6时StringTable在永久代的常量池里,1.8之后在堆中(方法去变成了直接内存里的元空间);
因为旧方案回收效率不高,会占用大量内存,而放到堆中只要触发Minor gc就会清理
三. 调优
StringTable底层实现类似于HashMap,数组+链表
当字符串常量数据量很大时,可以调整-XX:StringTableSize=桶个数,让它稍大一点,这样平均每个桶对应的链表不会太长