在 Java 中陣列是以值傳遞還是以引用傳遞
本教程介紹了在 Java 中按值或引用傳遞的陣列。
當我們呼叫一個方法時,它的引數可以作為值或引用傳遞。在討論這兩個問題之前,讓我們先了解兩個術語:
- callee:這是另一個方法呼叫的方法
- caller:這是呼叫另一個方法的方法
現在讓我們瞭解什麼是按值傳遞和按引用傳遞。
什麼是 Java 中的按值傳遞
當我們說引數是按值傳遞時,實際引數的值在記憶體中被複制了。
呼叫者和被呼叫者維護兩個具有相同值的自變數。如果被呼叫者修改了引數值,我們看不到呼叫者的變化。
要點:
- 被呼叫者無權訪問呼叫程式碼中的原始元素。
- 將資料(引數值)的副本傳送給被呼叫者。
- 對傳遞變數的更改不會影響最終值。
什麼是 Java 中的按引用傳遞
當我們說引數通過引用傳遞(也稱為按地址傳遞)時,它意味著將呼叫函式中的引數的引用傳遞給相應的形參。
在這種情況下,會製作實際引數地址的副本。呼叫者和被呼叫者對引數使用相同的變數,因此,如果被呼叫者修改引數變數,我們可以看到呼叫者變數的變化。
要點:
- 被呼叫者引用呼叫程式碼中的程式設計元素。
- 傳遞儲存資料的記憶體地址而不是值。
- 對值的任何更改都會影響原始資料
Java 是按值傳遞的
與 C++ 不同,在 Java 中,我們只能將引數作為值傳遞。但是有一個問題:當物件作為引數傳遞時,它們的引用作為值傳遞給被呼叫者。
換句話說,即使 Java 嚴格按值傳遞,它的行為與物件的引用傳遞一樣。讓我們用一些例子來更好地理解這個概念。
在 Java 中傳遞原始資料型別
在下面的程式碼中,我們將兩個整數作為引數傳遞給函式,然後我們更改它們的值。
由於在 Java 中引數是按值傳遞的,因此該函式維護了一個單獨的引數副本。我們對引數所做的任何更改都只在函式副本中進行,而不是在主函式(呼叫者)維護的副本中。
因此,我們在函式呼叫完成後列印值時得到原始值。看下面的示例程式碼:
public class SimpleTesting {
static void JE_function(int n1, int n2) {
n1 = -232;
n2 = -90;
}
public static void main(String args[]) {
int JE_numa = 6932;
int JE_numb = 8934;
System.out.println("Numbers before function call :" + JE_numa + " and " + JE_numb);
JE_function(JE_numa, JE_numb);
System.out.println("Numbers after the JE_function call :" + JE_numa + " and " + JE_numb);
}
}
輸出:
Numbers before function call:6932 and 8934
Numbers after the JE_function call:6932 and 8934
在 Java 中傳遞陣列
當涉及到物件時,對物件的引用是通過值作為引數傳遞的。
在下面的程式碼中,我們傳遞一個陣列作為引數,當我們列印物件(陣列)的值時,會列印一個記憶體位置。這與物件變數儲存儲存物件的記憶體位置有關。
看下面的示例程式碼:
public class SimpleTesting {
static void JE_function(String[] sentence) {
System.out.println(sentence);
}
public static void main(String args[]) {
String[] sent = {"I", "Love", "Delftstack"};
JE_function(sent);
}
}
輸出:
[Ljava.lang.String;@442d9b6e
使用上面的程式碼,我們嘗試傳達對作為引數傳遞的陣列的引用。因此,如果我們更改陣列的值(不是記憶體位置),更改將反映在被呼叫方中。
看下面的示例程式碼:
public class SimpleTesting {
static void JE_function(String[] sentence) {
sentence[1] = "Visit";
}
public static void main(String args[]) {
String[] sent = {"I", "Love", "Delftstack"};
System.out.println("Sentence before calling the function");
for (String word : sent) {
System.out.println(word);
}
JE_function(sent);
System.out.println("Sentence after calling the function");
for (String word : sent) {
System.out.println(word);
}
}
}
輸出:
Sentence before calling the function
I
Love
Delftstack
Sentence after calling the function
I
Visit
Delftstack
從上面的程式碼可以看出,對陣列的任何更改都會反映在主塊中。
把它想象成兩個朋友正在做一個專案。朋友所做的任何工作都會反映在整個專案中。
在這種情況下,該函式引用主塊使用的相同陣列。