1.String的基本特性
String的String Pool是一個固定大小的Hashtable,默認值大小是長度是1009.如果放進String Pool的String 非常多,就會造成Hash沖突嚴重,從而導致鏈表會很長,而鏈表很長的直接影響是調用String.intern時性能會大幅下降;
使用-XX:StringTableSize可以設置StringTable的長度
在JDK6中StringTable時固定的,就是1009的長度,所以常量池的字符串過多,就會導致效率下降很快,StringTableSize設置沒有要求;
在JDK7中,StringTable的長度默認值是60013,StringTableSize設置沒有要求;
在JDK8中,設置StringTable的長度,1009是可設置的最小值;
2.使用String類型常量池的方式
1.使用雙引號方式聲明對象:String str =“String”;
2.使用String類提供的intern()方法
3.不同JDK版本String常量池的存放位置
1.JDK6及以前,String常量池存放在永久代上;
2.JDK7后,字符串常量池調整存放在Java堆內;
所有的字符串都保存在堆中,和其他普通對象一樣,在進行調優應用時僅需要調整堆的大小就可以了;
4.字符串拼接操作
1.常量與常量的拼接結果放在常量池當中, 原理是編譯器優化
2.常量池不會存在相同內容的常量
3.只要其中有一個時變量,結果就在堆中相當於new了一個對象。變量拼接的原理是StringBuilder
4.如果拼接的結果調用intern()方法,則主動將常量池中還沒有的字符串對象放入池中,並返回此對象 地址
public void test(){ String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE" + "hadoop";//編譯期優化 //如果拼接符號的前后出現了變量,則相當於在堆空間中new String(),具體的內容為拼接的結果:javaEEhadoop String s5 = s1 + "hadoop"; String s6 = "javaEE" + s2; String s7 = s1 + s2; System.out.println(s3 == s4);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false //intern():判斷字符串常量池中是否存在javaEEhadoop值,如果存在,則返回常量池中javaEEhadoop的地址; //如果字符串常量池中不存在javaEEhadoop,則在常量池中加載一份javaEEhadoop,並返回次對象的地址。 String s8 = s6.intern(); System.out.println(s3 == s8);//true }
5.字符串拼接的底層實現不一定使用StringBuilder,當符號拼接左右兩邊為字符串常量或常量引用,會在編譯期優化
public void test1(){ final String s1 = "a"; final String s2 = "b"; String s3 = "ab"; String s4 = s1 + s2; System.out.println(s3 == s4);//true }
6.StringBuilder使用優化:在基本確定字符串長度時,盡量初始化一個對應大小的初始容量值,避免擴容造成性能消耗