東西是轉的,供大家學習。有些東西要想徹底的記住就是徹底的瞭解它。
public class Untitled1 {
public Untitled1() {
}
public static void main(String[] args) {
Untitled1 untitled11 = new Untitled1();
String s1="STRING類的值是不是會變的->";
String s2=s1;
System.out.println(s2);
s1+="加個試試"; //String 賦值實際上這個是NEW了一個新的對象了,S1變了
System.out.println(s2); //S2沒有變,這是因為S2指向的地址還是最早的s1所在的地址
StringBuffer b1=new StringBuffer("StringBuffer類的值是會變的->");
StringBuffer b2=b1;
b2.append("加個試試");//StringBuffer賦值,操作b2還是那個對象,
System.out.println(b1);//所以加一個字元進去b1指向的對象的值已經變了哦
}
}
結果:
STRING類的值是不是會變的->
STRING類的值是不是會變的->
StringBuffer類的值是會變的->加個試試
摘錄:
CSDN:
這裡的"可變"和"不可變",和是不是final沒有關係
舉個例子:
String str1 = "hello";
String str2 = "world";
String str1 = str1 + str2;//這裡所做的內部操作,其實不是把str1的內容改變為原str1+str2的內容這麼簡單, 而把建立一個新的String, 內容為str1 + str2的內容,然後再把str1這個引用重新指向新建立的String, 這就是上面說的String不可變.
而如果是StringBuffer的話,則直接更改str1的內容,而不是先建立一個新的StringBuffer
使用 StringBuffer 主要就是在效能上的考慮。
String 是一種非常常用的資料類型,但由於 String 是不可變對象,在進行 String 的相關操作的時候會產生許多臨時的 String 對象。
而 StringBuffer 在操作上是在一個緩衝中進行的,效能當然優越得多。
不過,一般做為簡單的字串傳遞和其它操作,只不要改變字串內容的操作,用 String 效率會高一些。
其他
記得以前在網上看到一篇關於java面試題的文章,裡面好像有個題就是關於String與StringBuffer的,具體的記不清了,大概內容如下:
請說出下面代碼塊存在的問題:
String tmp = “”;
for(int i=0;i<n;I++){
tmp +=”x”;
}
當時網上有人只是簡單的說了要改用StringBuffer,這個存在效率問題,而沒有進一步說明,其實我也很鬱悶,是什麼效率問題呢?“顧名思義,StringBuffer之所以效率好,應該是它提供了緩衝機制吧”,我想很多朋友是這樣想的吧,HOHO。
當昨天晚上讀到Effective java一書的時候,我才恍然大悟,原來String是一個支援非可變性的類,這種類的特點是狀態固定(不存在任何修改對象的方法),在該對象的生存周期內,它的值是永遠不變的(它是安全執行緒的),它們更容易設計、實現、使用,不易出錯,更加安全。
由於String類是支援非可變性的,所以,當執行tmp +=”x”的時候,實際上是另外建立了一個對象,而tmp原來指向的那個對象就成了垃圾(當它沒有其它引用的時候),這樣的話一個迴圈就會產生n多個物件,可以相象記憶體的浪費,怕怕。
先看一下String類中substring方法的實現
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
從藍色部份可以看出,它是重新建立了一個新的對象,符合“支援非可變性”的原則,但這卻也顯示出了非可變類的真正惟一的缺點,就是“對於每一個不同的值都要求一個單獨的對象”。
那為什麼String要設計成非可變類呢?我覺得String是java中使用最為頻繁的一個類,只有使其支援非可變性,才有可能避免一系列的問題,比如說:
String a,b,c;
a=”test”;
b=a;
c=b;
processA(){
……..
}
ProcessB(){
……..
}
ProcessC(){
……..
}
當String支援非可變性的時候,它們的值很好確定,不管調用哪個方法,都互不影響,如果它不支援的話,那麼我無法想象其結果。
StringBuffer做為String的“配套類(companying class)”,它的作用就是為瞭解決上述問題的,StringBuffer扮演了String的可變更配置套類角色。非可變類本質上是安全執行緒的,它們不要求做同步處理,我們可以將其共用給所有使用者,讓所有的“用戶端程式員”都可以直接使用此類而不需要做任何額外的工作。
public static void main(String[]arg) {
String a ="ssss";
String b = a;
if (a ==b)
System.out.println("a == b");//地址相同
if (a.equals(b))
System.out.println("a equals b");//內容相同
}
運行結果:
a == b
a equals b