深入理解String、StringBuffer、StringBuilder

三者在執行速度方面的比較:StringBuilder > StringBuffer > String

由於StringBuilder、StringBuffer都繼承自抽象類AbstractStringBuilder,他們的append、replace、delete、insert、indexOf、reverse方法的實現都是由AbstractStringBuilder實現的。不同的是StringBuffer做了同步處理,是線程安全的,StringBuilder是非線程安全的。

因此,在下面和String比較的時候就拿StringBuffer做比較。

String和StringBuffer主要有2個區別:
1.String類對象爲不可變對象,一旦修改了String對象的值,隱性重新創建了一個新的對象,釋放原String對象,StringBuffer類對象爲可修改對象,可以通過append()方法來修改值
2.String類的性能遠不如StringBuffer類。

String:
1.是對象不是原始類型,是引用類型。
2.String 是final類,不能被繼承,一旦被創建,就不能修改它的值.
3.底層用char[]來實現。
4.在用”+”進行字符串連接的時候,底層是新建一個String對象,通過新建一個StringBuilder或StringBuffer對象,調用其append方法,然後調用toString方法(在調用toString方法的時候會再創建一個String對象),返回給新建的String對象。其中會頻繁的創建新對象,增加了虛擬機GC的工作量,頻繁字符串連接的時候不推薦使用。

StringBuffer:
1.是一個可變對象,當對他進行修改的時候不會像String那樣重新建立對象。
2.底層用char[]來實現。
3.它只能通過構造函數來創建:

StringBuffer sb1 = new StringBuffer(); //創建一個長度爲16的StringBuffer對象,內容爲空。
StringBuffer sb2 = new StringBuffer(10); //創建一個長度爲10+16的StringBuffer對象,內容爲空。
StringBuffer sb3 = new StringBuffer("abc"); //創建一個長度爲3+16的StringBuffer對象。


4.對象被建立以後,在內存中就會分配內存空間,並初始保存一個null.向StringBuffer中賦值的時候可以通過它的append()方法.
sb.append("hello");
在調用append()方法的時候會先判斷StringBuffer底層char[]的長度,如果長度不夠用,就對char[]進行擴展,新長度爲原來長度的2倍+2。

總結:
1.在字符串連接操作中StringBuffer的效率要比String高。
2.如果沒有頻繁的字符串連接,可以用String,如果有頻繁的字符串連接,推薦用StringBuffer(線程安全)或者StringBuilder(非線程安全)。

 

3.StringBuffer之間的比較,要先調用toString()方法,再調用equals()方法作比較。

 

 

StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb1.equals(sb2));//結果false
System.out.println(sb1.toString().equals(sb2.toString()));//結果true

 

4.

String s1 = "abc";
String s2 = "abc";
s1==s1;//結果爲true

是因爲聲明s1,s2的時候這個”abc”是放在JVM內存中的常量池中,s1和s2都指向這個地址。因此在比較的時候s1,s2指向的爲內存中的同一個地址,所以會相等。

 

5.關於”+“連接String

將class文件反編譯後:

我們可以看出JVM在進行String連接的時候,實際上是新建了一個StringBuilder,然後進行運算。

原文鏈接:http://www.wekri.com/2015/07/15/java/String_StringBuffer_StringBuilder 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章