[英]Clarification on java pass-by-value
我對以下代碼為什么不更改Node a的數據感到困惑:
public class Node{Node next; int data;}
public static void change(Node a)
{
a = a.next;
}
public static void main(String [] args){
Node a = new Node();
Node b = new Node();
a.next = b;
a.data = 1;
b.next = null;
b.data = 2;
change(a);
System.out.print(a.data); //Still 1, why isn't it changed to 2?
}
由於Node是一個對象,它的引用不是通過值傳遞給方法更改嗎? 這意味着對傳入的Node所做的任何更改實際上都應該更改該節點?
這是因為在Java中,您是通過引用副本調用方法的。
這意味着當您調用change(a);
Java基本上會創建引用a
的副本,這將是public static void change(Node a)
的傳入參數。 然后,在方法內部,您將更改復制的引用以指向其他位置。 一旦您的方法返回,這將無效。
盡管之間沒有方法,但此完全相同的代碼將起作用。
這樣做a = a.next;
而不是change(a)
,現在您的a.data
將是2
。
您的更改方法將執行空的分配。 變量a
設置為下一個節點,但未從方法返回。 更改將僅在方法范圍內可用。 您可以更改:
public static Node change(Node a)
{
return a.next;
}
並調用:
a = change(a);
System.out.print(a.data);
運算符=更改“ a”的參考。 使用方法“ set(Node nodeToCopy)”,該方法將復制當前節點中的所有“ nodeToCopy”。
public class Node{
Node next;
int data;
public void set(Node Other) {
next = other.next;
data = other.data;
}
}
public static void change(Node a)
{
a.set(a.next);
}
但是! 這不是您要執行的操作,因為它會破壞對象a和b。 您沒有其他解決方案:
Node a = new Node();
Node b = new Node();
Node i = a;
a.next = b;
a.data = 1;
b.next = null;
b.data = 2;
System.out.print(i.data); //it's 1
i = i.next;
System.out.print(i.data); //it's 2
用
public static void change(Node a)
a 不是 alias
而是一個新變量,其中包含傳遞的參數的地址。
所以,
a.data=100;//would change value of the actual Node in main
[NewVariableWithAddressOfa].data=100;
但是當你這樣做
a = a.next;
[NewVariableWithAddressOfa]=[NewVariableWithAddressOfa].next;
您正在分配b的地址,該地址將不會更改原始Node a
因為正如我之前所說a
in in change
方法是一個新變量!
請參閱按值調用,以了解為何對參數的賦值沒有(也不會)改變調用者中的變量綁定的原因:
.. 在按值調用中,對參數表達式進行求值,並將結果值綁定到函數中的相應變量 .. 如果函數或過程能夠為其參數分配值,則僅分配其本地副本-即,當函數返回時,[用作函數調用參數的任何變量在調用者的范圍內都是不變的 。
按值調用不是一個單獨的評估策略,而是一系列評估策略,其中在將函數的參數傳遞給函數之前先對其進行評估 。
請注意上面有意使用的不同術語變量,參數和參數 。 可以很容易地在任何地方更改被更改的對象 - 通過[Object] Sharing的調用可以始終描述該對象 ; 但是,這與按值調用正交。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.