2014-10-19 43 views
4

首先,我知道java中的字符串是不可變的。關於Java中的字符串不變性

我有一個關於字符串不變性問題:

public static void stringReplace (String text) 
{ 
    text = text.replace ('j' , 'c'); /* Line 5 */ 
} 
public static void bufferReplace (StringBuffer text) 
{ 
    text = text.append ("c"); /* Line 9 */ 
} 
public static void main (String args[]) 
{ 
    String textString = new String ("java"); 
    StringBuffer textBuffer = new StringBuffer ("java"); /* Line 14 */ 
    stringReplace(textString); 
    bufferReplace(textBuffer); 
    System.out.println (textString + textBuffer); //Prints javajavac 
} 

但是,如果我們寫:

public static void bufferReplace (StringBuffer text) 
{ 
    text = text.append ("c"); /* Line 9 */ 
} 
public static void main (String args[]) 
{ 
    String textString = new String ("java"); 
    StringBuffer textBuffer = new StringBuffer ("java"); /* Line 14 */ 
    textString = textString.replace ('j' , 'c'); 
    bufferReplace(textBuffer); 
    System.out.println (textString + textBuffer); //Prints cavajavac 
} 

的事情是我所期望的第一個例子將打印一樣的第二印刷。原因是當我們將textString傳遞給我們實際傳遞給textString的函數時。現在在函數體另一個字符串被text.replace ('j' , 'c')生產,我們分配給該字符串,我們在傳遞的字符串的引用。 在第二個例子中,我只分配給由textString.replace ('j' , 'c');產生的testString這個字符串的引用。爲什麼有這麼差異?

遵循這個原因,其結果必須是相同的。怎麼了?

+3

Btw。如果您不需要同步,請使用StringBuilder而不是StringBuffer。 – 2014-10-19 10:53:49

+0

@ jakub.petr爲什麼這麼重要? – 2014-10-19 10:54:29

+2

@ St.Antario因爲'StringBuffer'比'StringBuilder'慢得多 – msrd0 2014-10-19 10:55:36

回答

7

在第二個例子textString = textString.replace ('j' , 'c');發生在你的主要方法,所以textString變量被賦予了新的String,你看到新的String的價值打印你的輸出時。

在第一個示例中,它不會發生,因爲調用stringReplace方法不能更改傳遞給它的參考String。因此,您看到的輸出就好像您從來沒有撥打stringReplace(textString)一樣。

這一切都歸結到Java是一個傳值的語言。您不能更改傳遞給方法的對象引用,因爲該引用是按值傳遞的。如果String不是不可變的,那麼可以通過調用改變其狀態的String方法來更改傳遞給方法的String實例(如果存在這種方法的話),但是仍然無法爲該方法的參數分配新的String引用並將其反映在方法的調用者中。

+0

有趣。如果您提供了對JLS的規範性參考,那將會很好。 – 2014-10-19 10:53:18

+4

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.1:*當方法或構造函數被調用(§15.12)時,實際參數表達式在執行方法體或構造函數之前,初始化新創建的參數變量,每個聲明的類型。* Java是按值傳遞的。 – 2014-10-19 10:57:54

+0

@JBNizet如果它傳遞值爲什麼_stringBuffer_已經發生了變異?它通過價值傳遞。 – 2014-10-19 16:13:16