2011-09-21 79 views
0

可能重複:
Java pass by reference issueJava的淺層和深層複製JLS

在我下面的代碼,methodA將被調用,然後委託調用methodB,這樣做,methodB用字符串文字「bbb」分配輸入參數,但是,返回methodA,字符串文字不在那裏,JLS的哪一部分定義了這種行爲?

package sg.java.test2; 

public class TestApple { 
    public static void main(String args[]){ 
     methodA(); 
    } 

    public static void methodA(){ 
     String a = null; 

     methodB(a); 

     System.out.println(a); 
    } 

    public static void methodB(String a){ 
     a = new String("bbb"); 
    } 
} 

回答

4

這是一個按值傳遞vs通過引用問題。 Java只是傳遞值。當你調用

methodB(a)

參考a被複制;在methodB的情況下,a是具有與methodA中相同的值的不同變量。所以當你在methodB中更改它時,a中的methodA仍然指向原始字符串。

這裏發揮的另一個問題是字符串是不可變的,所以一旦設置了字符串就不能改變字符串的值。來自文檔。

字符串是恆定的;它們的值在創建 後無法更改。

你可以做的是

a = methodB();

methodB返回"bbb"。沒有理由通過a因爲你沒有操作它;我認爲你只是試圖在調用methodB的環境中嘗試更改a,這是你不能做的。

最後,JLS的相關部分是8.4.1,它說

當該方法或構造函數被調用(§15。12)中, 實際參數表達式的值初始化新創建的參數 變量,每個聲明的類型,在執行體的 之前的方法或構造函數。出現在 DeclaratorId中的標識符可以用作方法主體或構造函數體中的簡單名稱,以引用形式參數。

+0

此外,如果我試圖傳遞的參數不是一個字符串,並且可變的東西,比如一個普通的域對象,上述情況是否仍然如此? –

+1

正確的下巴。我爲你的答案添加了一個例子。 –

+0

感謝好友的擡頭。 –

2

Java是按值傳遞,而不是通過引用。

方法簽名是簡寫此:

methodB() { 
    String a = arguments[0]; 

即它是一個差基準。當您分配給'a'時,您將分配給作爲方法簽名一部分創建的參考'a',而不是您在代碼塊中聲明的'a',其中包含對methodB()的調用。

但是,如果它是一個對象,則可以修改該值。

class MyObj { 
    String prop; 
    public MyObj(String s) { prop = s; } 
    public MyObj() { } 
} 

public void methodB(MyObj o) { 
    o.prop = "foo"; 
} 

public void methodA() { 
    MyObj a = new MyObj(); 
    System.out.println(a.prop); // null 
    methodB(a); 
    System.out.println(a.prop); // foo 
} 
+1

java是通過值dammit! – hvgotcodes

+1

對不起,本意是說**不**通過參考...修正 –

+0

爲什麼a.foo從methofB(a)返回後給出「foo」.. –