2011-12-31 139 views
0

我遇到過兩種情況。如何傳遞Object作爲參數與傳遞Array作爲參數不同?

其中一個數組作爲參數傳遞給方法,如果它在被調用方法中更新,它也反映在調用方法中。

但在第二種情況下,字符串對象作爲參數傳遞。該對象在被調用的方法中更新,但它不反映在調用方法中。

我想了解兩者之間的區別,即使在這兩種情況下,值(參考)都作爲參數傳遞。請參閱下面的片段。

方案1:

class Test { 
public static void main(String[] args){ 
int a[] = {3,4,5}; 
changeValue(a); 
System.out.println("Value at Index 1 is "+a[1]); 
} 
public static void changeValue(int b[]){ 
b[1] = 9; 
} 
} 

輸出:

Value at Index 1 is 9 

在此,參考(存儲器地址)相關的陣列a被傳遞給changeValue。因此,b只是指向與a相同的地址。 因此,無論我說的是b[1]還是a[1],都是指相同的內存地址。

方案2:

public class Test { 
public static void main(String[] args){ 
String value = "abc"; 
changeValue(value); 
System.out.println(value); 
} 
public static void changeValue(String a){ 
a = "xyz"; 
} 
} 

輸出:

abc 

如果我在此適用同樣的邏輯,字符串對象值的參考(存儲器地址)被傳遞給changeValue,其通過a收到。 因此,現在的a應該指的是與VALUE相同的內存位置。因此,執行a="xyz"時,應該用"xyz"代替​​。

有人可以指出我的理解出錯的地方嗎?提前致謝!!

回答

0

謝謝大家的答案和更新..

我瞭解的情況1和2,如下的區別..

在方案1中,數組引用傳遞。被調用的方法只是更新引用指向的元素之一。

雖然在場景2中傳遞了引用,但是當被調用的方法將「xyz」賦值給引用變量(指針)時,它實際上會創建一個新的String對象,並將其引用賦值給本地引用變量'a '(指針現在指向一個不同的目標)。

在調用方法的代碼是不如

a = new String("xyz"); 

因此,在調用方法的對象和方法調用是絕對不同的,並且indepenedent和具有彼此沒有關係。

同樣也可以發生在方案1中,如果不是做

b[1] = 9; 

我會用

b = new int[] {8,9,10}; 

我明白,可變性的基本面會來的動作,讓我有完成如下...

String a="abc"; 
a="xyz"; 

在這種情況下,對象「abc」被指向由'a'。當'a'被賦予指向新對象「xyz」的職責時,將創建一個新對象「xyz」,該對象不會替換現有對象「abc」。即「abc」仍然存在,但沒有參考變量來保持其自身可訪問。這種不可替代的財產是因爲字符串的不可變性。

2

Java按值傳遞其所有參數。這意味着指向String的指針的副本被創建,然後傳遞給方法。該方法然後使指針指向另一個對象,但原始指針仍然指向相同的字符串。

2

這是不一樣的東西:

    在第一示例
  • ,傳遞數組引用作爲參數,因此你正確地期望它通過直接操作參考被改變;
  • 但在第二個例子中,你傳遞了一個對象引用,當然 - 但你改變了引用本身的方法。方法返回時,不會反映對a的更改。

考慮任何對象:

public void changeObj(Object o) 
{ 
    o = new Whatever(); 
} 

一個新的對象被創建,但在調用者也不會改變o。這裏也是一樣。

+1

不變性是這裏的一種紅鯡魚。 – 2011-12-31 16:28:18

+0

是的,在這種情況下,它根本就沒有關係。編輯。 – fge 2011-12-31 16:33:10

1

這裏的區別很簡單,它實際上並不是關於字符串的不可變性,因爲其他一些答案(現在編輯或刪除)最初可能已經暗示。在一個版本中(使用字符串),你已經重新分配了引用,而在其他版本中(使用數組),你還沒有。

array[0] = foo; // sets an element, no reassignment to variable 
array = new int[] { 1,2,3 }; // assigns new array 
obj = "hey"; // assigns new value 

當您重新分配變量,你不打算遵守的方法之外的變化。如果在不重新分配數組變量的情況下更改數組的元素,則會看到這些更改。當您在對象上調用setter而不重新指定對象的實際變量時,您將觀察這些更改。當你覆蓋變量(新數組,新賦值,創建新對象等)時,這些變化將不被察覺。

參數按值傳遞(或複製)。方法內部的變量與開始時外部的變量具有相同的值。變量沒有鏈接,並且它們不是彼此的別名。他們碰巧包含相同的價值。一旦你將價值重新分配給其中的一個,那就不再是真的了!外部變量不受內部變量或甚至另一個局部變量的影響。考慮

Foo foo = new Foo(); 
Foo other = foo; 
foo.setBar(1); 
int bar = other.getBar(); // gets 1 
foo = new Foo(); 
foo.setBar(42); 
int bar2 = other.getBar(); // still gets 1 

fooother只引用一個時間同一個對象。一旦foo被分配了一個新的對象,變量不再有任何共同之處。重新分配方法中的參數變量也是如此。

1

你正在做不同的事情;用字符串設置參數值,用數組設置屬於的參考。

對於你需要嘗試陣列基準設定爲一個新的數組等效陣列例如:

public static void changeValue(int[] b) { 
    b = new int[] { 42, 60 }; 
} 

原始數組不會改變。