簡體   English   中英

將對象作為參數傳遞與將數組作為參數傳遞有何不同?

[英]How passing an Object as argument differs from passing an Array as argument?

我遇到了兩種情況。

一種將數組作為參數傳遞給方法的方法,如果在調用的方法中對其進行更新,則它也將反映在調用的方法中。

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

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

方案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" ,應將"abc"替換為"xyz"

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

Java通過值傳遞其所有參數。 這意味着將創建指向String的指針的副本,然后將其傳遞給該方法。 然后,該方法使指針指向另一個對象,但是原始指針仍指向同一String。

這不是同一件事:

  • 在第一個示例中,您將數組引用作為參數傳遞,因此您可以正確地期望直接操作該引用來更改它;
  • 但是,在第二個示例中,您肯定傳遞了對象引用-但是您在方法中更改了引用本身。 方法返回時,不會反映對a更改。

考慮任何對象:

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

一個新的對象被創建,但它不會改變o在調用者。 同樣的事情在這里發生。

此處的區別很簡單,實際上與字符串的不變性無關,因為其他答案(現在已被編輯或刪除)可能最初就暗示了。 在一個版本(帶有字符串)中,您已經重新分配了引用,而在另一個版本(帶有數組)中,您沒有了。

 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分配了一個新對象,變量就不再具有任何共同點。 對於方法內部的參數變量的重新分配也是如此。

您正在做不同的事情; 使用設置參數值的字符串,使用數組設置屬於引用的內容。

對於等效的數組示例,您需要嘗試將數組引用設置為新數組:

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

原始數組不會更改。

謝謝大家的答復和更新。

我了解方案1和2之間的區別如下。

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

在方案2中,雖然傳遞了引用,但是當被調用的方法將“ xyz”分配給引用變量(指針)時,它實際上創建了一個新的String對象,並且其引用被關聯到本地引用變量“ a”(現在為Pointer指向不同的對象)。

調用方法中的代碼與

a = new String("xyz");

因此,被調用方法和調用方法中的對象是絕對不同且獨立的,彼此之間沒有關系。

如果不這樣做,情況1也可能發生相同的情況

b[1] = 9; 

我本來會用

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

我了解,如果我可以像下面那樣做,則可變性基本原理將付諸實踐。

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

在這種情況下,對象“ abc”由“ a”指向。 當為“ a”分配了指向新對象“ xyz”的職責時,將創建一個新對象“ xyz”,而不替換現有對象“ abc”。 也就是說,“ abc”仍然存在,但是沒有參考變量來保持其自身可訪問性。 此不可替換屬性是由於String的不可變性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM