三者在執行速度方面的比較: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