天天看點

String 與String Buffer 差別

JVM是怎樣處理字元串的呢?

  Java虛拟機會維護一個内部的滞留字元串對象的清單(唯一字元串的池)來避免在堆記憶體中産生重複的String對象。當JVM從class檔案裡加載字元串字面量并執行的時候,它會先檢查一下目前的字元串是否已經存在于滞留字元串清單,如果已經存在,那就不會再建立一個新的String對象而是将引用指向已經存在的String對象,JVM會在内部為字元串字面量作這種檢查,但并不會為通過new關鍵字建立的String對象作這種檢查。當然你可以明确地使用String.intern()方法強制JVM為通過new關鍵字建立的String對象作這樣的檢查。這樣可以強制JVM檢查内部清單而使用已有的String對象。

  是以結論是,JVM會内在地為字元串字面量維護一些唯一的String對象,程式員不需要為字元串字面量而發愁,但是可能會被一些通過 new關鍵字建立的String對象而困擾,不過他們可以使用intern()方法來避免在堆記憶體上建立重複的String對象來改善Java的運作性能。下一小節會向大家展示更多的資訊。

滞留字元串的優化作用

  同一個字元串對象被重複地建立是不必要的,String.intern ()方法可以避免這種情況。下圖說明了String.intern()方法是如何工作的,String.intern()方法檢查字元串對象的存在性,如果需要的字元串對象已經存在,那麼它會将引用指向已經存在的字元串對象而不是重新建立一個。下圖描繪了使用了intern()方法的字元串字面量和字元串對象的建立情況。

StringBuffer的預設行為:

  StringBuffer在内部維護一個字元數組,當你使用預設的構造函數來建立StringBuffer對象的時候,因為沒有設定初始化字元長度,StringBuffer的容量被初始化為16個字元,也就是說預設容量就是16個字元。當StringBuffer達到最大容量的時候,它會将自身容量增加到目前的2倍再加2,也就是(2*舊值+2)。

  如果你使用預設值,初始化之後接着往裡面追加字元,在你追加到第16個字元的時候它會将容量增加到34(2*16+2),當追加到34個字元的時候就會将容量增加到70(2*34+2)。無論何事隻要StringBuffer到達它的最大容量它就不得不建立一個新的字元數組然後重新将舊字元和新字元都拷貝一遍——這也太昂貴了點。是以總是給StringBuffer設定一個合理的初始化容量值是錯不了的,這樣會帶來立竿見影的性能增益。

  我利用兩個StringBuffer重新測試了上面的StringTest4.java代碼,一個未使用初始化容量值而另一個使用了。這次我追加了50000個’hello’對象沒有使用+操作符。差別是我使用StringBuffer(250000)的構造函數來初始化第二個 StringBuffer了。

關鍵點

1. 無論何時隻要可能的話使用字元串字面量來常見字元串而不是使用new關鍵字來建立字元串。

2. 無論何時當你要使用new關鍵字來建立很多内容重複的字元串的話,請使用String.intern()方法。

3. +操作符會為字元串連接配接提供最佳的性能——當字元串是在編譯期決定的時候。

4. 如果字元串在運作期決定,使用一個合适的初期容量值初始化的StringBuffer會為字元串連接配接提供最佳的性能

參考:http://java.chinaitlab.com/WebServices/390218.html