String
String是不可變的類(lèi)滥搭,即final 類(lèi)瑟匆,String底層使用final Char[] 來(lái)實(shí)現(xiàn)无午,不可變的字符數(shù)組。
當(dāng)我們進(jìn)行字符串拼接的時(shí)候次泽,如下
String str = "a" + "b";
這個(gè)時(shí)候會(huì)在堆上創(chuàng)建三個(gè)String對(duì)象意荤,分別是str1="a"紫谷,str2="b"瞒窒,str="ab".因此如果有大量的這種字符串拼接等操作的話拔稳,會(huì)影響程序的運(yùn)行速度。
String的定義如下:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {...}
StringBuffer
因此我們引入了StringBuffer類(lèi),它的底層實(shí)現(xiàn)是可變的字符串?dāng)?shù)組,當(dāng)我們執(zhí)行append方法的時(shí)候,操作的對(duì)象是StringBuffer對(duì)象本身,而不會(huì)像String那樣產(chǎn)生多個(gè)中間對(duì)象拆檬。但是有個(gè)問(wèn)題,StringBuffer在執(zhí)行某些方法的時(shí)候,比如append方法选酗,會(huì)對(duì)方法體加鎖(synchronized)保證線程安全。但是我們知道加鎖和釋放鎖是需要耗費(fèi)資源的殿衰,因此在進(jìn)行大量的、業(yè)務(wù)不需要線程安全的情況下使用StringBuffer就顯得效率低下,因此就有了后面的StringBuilder類(lèi)惠昔。
StringBuilder
StringBuilder類(lèi)的絕大部分功能和StringBuffer都一樣,但是StringBuiler類(lèi)是線程不安全的饼齿,因此,相比與StringBuffer類(lèi)來(lái)說(shuō)僚楞,StringBuilder類(lèi)在執(zhí)行字符串拼接等操作的時(shí)候速度更快泉褐。
字符串常量池(String constant pool)
看看我們的代碼疲眷,你會(huì)發(fā)現(xiàn)String是真的頻繁得使用到几颜,Java為了避免在一個(gè)系統(tǒng)中產(chǎn)生大量的String對(duì)象,引入了字符串常量池样勃。
創(chuàng)建一個(gè)字符串時(shí)辉饱,首先會(huì)檢查池中是否有值相同的字符串對(duì)象乘寒,如果有就直接返回引用捏境,不會(huì)創(chuàng)建字符串對(duì)象;如果沒(méi)有則新建字符串對(duì)象凛捏,返回對(duì)象引用,并且將新創(chuàng)建的對(duì)象放入池中捺氢。但是藻丢,通過(guò)new方法創(chuàng)建的String對(duì)象是不檢查字符串常量池的,而是直接在堆中創(chuàng)建新對(duì)象摄乒,也不會(huì)把對(duì)象放入池中悠反。上述原則只適用于直接給String對(duì)象引用賦值的情況。
String str1 = new String("a"); //不檢查字符串常量池的
String str2 = "bb"; //檢查字符串常量池的
總的來(lái)說(shuō)馍佑,從兩個(gè)方面來(lái)對(duì)比String斋否、StringBuffer、StringBuilder拭荤,
執(zhí)行速度:StringBuilder > StringBuffer > String
應(yīng)用場(chǎng)景:
String: 少量的字符串操作
StringBuffer: 需要線程安全的字符串操作
StringBuilder: 在單線程或者不需要保證線程安全的情況下進(jìn)行大量字符串操作