這篇博客是對String的總結,注意,不是系統地講解String方方面面,想學String的所有知識,看看Java編程思想的字符串這一章就行,這篇博客只是對String一些細節問題的總結。整篇博客會比較零散,我儘可能系統地總結好,並且會持續更新。具體引用別人博客的地方,我會附上連接。html
Java字符串處理離不開這三個類。這裏總結下這三個類的區別,這裏參考了String、StringBuffer與StringBuilder之間區別。java
在執行效率上StringBuilder > StringBuffer > String。可是也有例外,詳情見下面的特殊的例子。編程
這點其實能夠解釋這三者執行效率的不一樣。主要緣由是String是不可變類(有興趣的同窗能夠看看String源碼,其值是private final char value[]定義的),其餘兩個類是可變類。每次對String進行改變時,其實是建立了新的對象,原來的對象會被GC回收掉。例以下面的代碼,在執行第二句後,s實際上已經只想了新的String,其值爲"abcd1",而以前的String對象"abcd"因爲沒有引用指向它,因此後面會被GC回收。安全
String s = "abcd"; s = s+1; System.out.print(s);// result : abcd1
線程安全:String, StringBuffer。app
線程不安全:StringBuilder。優化
String str = 「This is only a」 + 「 simple」 + 「 test」; StringBuilder builder = new StringBuilder("This is only a").append(" simple").append(" test");
這個例子是對執行效率的補充。這裏,生成str對象的速度簡直太快了,而這個時候StringBuffer竟然速度上根本一點都不佔優點。其實這是JVM的一個把戲,實際上:ui
String str = 「This is only a」 + 「 simple」 + 「test」;
其實就是:線程
String str = 「This is only a simple test」;
因此不須要太多的時間了。但你們這裏要注意的是,若是你的字符串是來自另外的String對象的話,速度就沒那麼快了,譬如:code
String str2 = 「This is only a」; String str3 = 「 simple」; String str4 = 「 test」; String str1 = str2 +str3 + str4;
這時候JVM會規規矩矩的按照原來的方式去作。htm
你們都知道String在比較內容相等時,用equals方法就行,這是由於String重寫了Object的equals方法。可是StringBuffer沒有重寫equals方法,因此不能用equals來比較。
因此咱們通常用toString()把StringBuffer轉換爲String,再利用equals來比較。
在Java中的String類已經重載的"+"。也就是說,字符串能夠直接使用"+"進行鏈接。你們都知道,大量用"+"操做的時候,會產生不少垃圾,因此通常用StringBuilder或者StringBuffer。(這部分參考了Java編程思想的第13章字符串)
而咱們在用javap反編譯的時候,發現編譯時仍然將"+"轉換成StringBuilder。所以,咱們能夠得出結論,在進行字符串鏈接時,實際上使用的是StringBuilder類的append()方法。
可是編譯器不會進行不少優化,每進行一次"+",就會建立一個StringBuilder對象,雖然Java有垃圾回收器,但這個回收器的工做時間是不定的。若是不斷產生這樣的垃圾,那麼仍然會佔用大量的資源。解決這個問題的方法就是在程序中直接使用StringBuilder類來鏈接字符串。