2012-08-03 23 views
7

初學Java的問題後並沒有改變,但我不明白怎麼稱呼按值(或參考)在下面的例子中工作 -爪哇 - 對象狀態的方法調用

怎麼來的字符串值沒有修改在我的自定義字符串對象處於退出方法後。 ?同樣的,其他類,如日期..

public class StringMadness { 

public static void main(String[] args) { 
    String s = "Native String"; 
    CustomStringObject cs = new CustomStringObject(); 
    System.out.println("Custom String Before: " + cs.str); 
    hello(cs); 
    System.out.println("Custom String After: " + cs.str); 

    System.out.println("Native String Before: " + s); 
    hello(s); 
    System.out.println("Native String After: " + s); 
} 

private static void hello(String t) { 
    t = "hello " + t; 
} 

private static void hello(CustomStringObject o) { 
    o.str = "hello " + o.str; 
    } 
} 

class CustomStringObject { 

String str = "Custom String"; 
} 

回答

16

比較這兩種方法:

private static void hello(String t) { 
    t = "hello " + t; 
} 

private static void hello(CustomStringObject o) { 
    o.str = "hello " + o.str; 
} 

在第一種情況下,你分配新的價值t。這對調用代碼沒有任何影響 - 您只需更改參數的值,並且所有參數都通過Java中的值傳遞。

在第二種情況下,你要指定一個新值o.str。這正在改變對象中的值所指的字段的值。調用者看到該更改,因爲調用方仍然具有對該對象的引用。

簡而言之:爪哇總是由值使用通,但你需要記住的類,變量(或實際上任何其他表達式)的值是一個參考,而不是一個對象。你不需要使用參數傳遞給看到這一點:

Foo foo1 = new Foo(); 
Foo foo2 = foo1; 
foo1.someField = "changed"; 
System.out.println(foo2.someField) // "changed" 

這裏的第二行的副本foo1價值爲foo2 - 兩個變量指向同一個對象,因此它並不重要變量,你用來訪問它。

+0

啊..我明白了。感謝....本來,我的'你好(CustomStringObject O)'被實例化一個新的實例,如'O =新CustomStringObject()'我注意到hello方法之外,在instanation從未有過任何影響。這就是觸發問題的原因。 – 2012-08-03 19:04:40

+0

@Jon很好的解釋。 Foo示例有所幫助。 +1 – 2014-03-06 04:52:09

+0

如果調用者傳遞空引用,那麼我觀察到被調用者修改並不反映給調用者。爲什麼它是這樣呢? – 2015-09-29 10:40:06

0

t將指向新的對象和範圍的只有方法,所以變化不可見之外。

第二種情況下,要更改值將被更新爲對象,所以這些變化的方法調用後可見。

+0

這不是因爲字符串是不可變的。即使這是一個StringBuilder,分配一個新值參數不會影響來電... – 2012-08-03 18:52:18

+0

@JonSkeet:同意。更新了我的答案。 – kosa 2012-08-03 18:53:09

4

有兩種方法之間的一個重要區別:使用hello(String)你想改變參考String,並與hello(CustomObject),給定一個參考,你使用的參考來改變對象的成員。

hello(String)採用對String的引用。在該函數中,您試圖更改參考指向哪個對象,但是您只是更改參考的傳值。所以你的改變不會反映在方法之外。

hello(CustomObject)給出一個參考的副本到一個對象,然後你就可以用它來改變實際的對象。將此視爲更改對象的內容。所以你的變化反映在調用者。

給定參考一個對象,你可以使用它的曝光方法改變對象/領域

0

因爲對於字符串你只是改變局部參數參考。

0

不起作用,因爲字符串是不可變的對象