學習了String類和StringBuffer類,現在從三分面來總結一下String、StringBuffer、StringBudder三者的區別:
- 是否可變:
String:底層利用字符數組保存字符串常量,是不可變的,因爲String類的原碼中有:private final char value[];
因爲有final修飾,所以String類的對象是不可改變的。所以每次修String對象的值時,實際上是生成了一個新的對象,而指針指向了新的String對象;
StringBuffer和StringBudder底層是利用字符數組保存字符串變量的,在jdk1.7中它們都繼承了AbstractStringBuilder類,而在AbstractStringBuilder類中有char[] value;
,所以這兩者對象是可變的;
執行速度:一般情況StringBudder > StringBuffer > String
String:因爲String對象是不可變的,所以每次修String對象的時候,實際上是生成了一個新的對象,而指針指向了新的String對象;所以經常改變內容的字符串最好不要用 String ,因爲每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以後, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。
StringBuffer:而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,再改變對象引用。
但是有特殊情況: String str = “abc” + “def”;StringBuffer Sb = new StringBuilder(“abc”).append(“ def”);這時這種情況下:String的速度就要比StringBuffer的速度要快,因爲這時jvm認爲String str = “abc” + “def”;其實是:String str = “abcdef”;所以速度當然很快,這裏說的是當String保存的字符串中有其他String的字符串時,速度就會變慢。是否線程安全:
String: String中的對象是不可變的,也就可以理解爲常量,顯然線程安全。
StringBuffer:是線程安全的,因爲對方法加了同步鎖或者對調用的方法加了同步鎖,部分方法原碼如下:
public synchronized int length() {
return count;
}
public synchronized int capacity() {
return value.length;
}
public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
StringBudder:並沒有對方法進行加同步鎖,所以是非線程安全的。部分方法原碼如下:
private StringBuilder append(StringBuilder sb) {
if (sb == null)
return append("null");
int len = sb.length();
int newcount = count + len;
if (newcount > value.length)
expandCapacity(newcount);
sb.getChars(0, len, value, count);
count = newcount;
return this;
}
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
- 對三者的使用意見:
1.如果要操作少量的數據用: String
2.單線程操作字符串緩衝區 下操作大量數據 :StringBuilder
3.多線程操作字符串緩衝區 下操作大量數據 : StringBuffer