簡介
許多Java程序員懷疑Java是按值傳遞還是按引用傳遞。本文概述了為什麼Java始終是按值傳遞。
首先,按值傳遞和按引用傳遞是什麼意思?
- 按值傳遞:方法參數值被複製到另一個變量,然後複製的對象被傳遞給方法。方法使用複製。
- 按引用傳遞:實際參數的別名或引用被傳遞給方法。方法訪問實際參數。
通常,這些術語的混淆是由於Java中的對象引用的概念。從技術上講,Java始終是按值傳遞,因為即使一個變量可能持有對象的引用,該對象引用也是一個值,代表對象在內存中的位置。因此,對象引用是按值傳遞的。
引用數據類型和基本數據類型都是按值傳遞的。了解更多關於Java中的數據類型。
除了理解數據類型外,還需要了解Java中的內存分配,因為引用數據類型和基本數據類型存儲方式不同。
展示傳值方式
以下示例演示了在Java中如何傳遞值。
該示例程序使用了以下類:
public class Balloon {
private String color;
public Balloon() {}
public Balloon(String c) {
this.color = c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
以下示例程序使用了一個通用方法swap()
,該方法交換兩個變量。另一個方法changeValue()
嘗試更改變量的值。
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); // 內存參考 = 50
Balloon blue = new Balloon("Blue"); // 內存參考 = 100
swap(red, blue);
System.out.println("After the swap method executes:");
System.out.println("`red` color value = " + red.getColor());
System.out.println("`blue` color value = " + blue.getColor());
changeValue(blue);
System.out.println("After the changeValue method executes:");
System.out.println("`blue` color value = " + blue.getColor());
}
// 通用交換方法
public static void swap(Object o1, Object o2){
Object temp = o1;
o1 = o2;
o2 = temp;
}
private static void changeValue(Balloon balloon) { // balloon = 100
balloon.setColor("Red"); // balloon = 100
balloon = new Balloon("Green"); // balloon = 200
balloon.setColor("Blue"); // balloon = 200
}
}
當您執行示例程序時,您將獲得以下輸出:
OutputAfter the swap method executes:
'red' color value = Red
'blue' color value = Blue
After the changeValue method executes:
'blue' color value = Red
該輸出顯示swap()
方法並未交換原始對象的顏色值。這有助於顯示Java是傳值方式,因為swap()
方法僅對原始對象參考值的副本進行操作。
這個swap()
方法測試可以用於任何編程語言,以檢查它是按值傳遞還是按引用傳遞。
解釋了swap()
方法的示例
當您使用new
運算符創建類的實例時,對象將被創建並且變量包含對象保存的內存中的位置。
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
這裡是swap()
方法執行時發生的步驟詳細說明:
-
假設
red
指向內存位置50,blue
指向內存位置100,這些是兩個Balloon
對象的內存位置。 -
當類使用
red
和blue
變量作為參數調用swap()
方法時,將創建兩個新的對象變量o1
和o2
。o1
和o2
同樣指向內存位置50和100。 -
以下的程式碼片段解釋了在
swap()
方法內發生的事情:public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100 Object temp = o1; // 將 o1 的物件參考值指定給 temp:temp = 50,o1 = 50,o2 = 100 o1 = o2; // 將 o2 的物件參考值指定給 o1:temp = 50,o1 = 100,o2 = 100 o2 = temp; // 將 temp 的物件參考值指定給 o2:temp = 50,o1 = 100,o2 = 50 } // 方法結束
-
o1 和 o2 的值已交換,但因為這些值是對於紅色和藍色記憶體位置的副本,因此對於紅色和藍色顏色值的值並未更改。
由於變數包含對象的引用,很容易錯誤地認為你正在傳遞引用並且 Java 是按引用傳遞的。但是,實際上你正在傳遞的是引用的副本,因此它是按值傳遞的。
示例 changeValue()
方法說明
在示例程序中,下一个方法会改变blue
变量所引用的对象的颜色值:
private static void changeValue(Balloon balloon) { // balloon = 100
balloon.setColor("Red"); // balloon = 100
balloon = new Balloon("Green"); // balloon = 200
balloon.setColor("Blue"); // balloon = 200
}
下面是changeValue()
方法中发生的步骤:
-
该类在
blue
变量上调用changeValue()
方法,该变量引用内存位置100。第一行创建了一个引用,也指向内存位置100。内存位置100处的对象的颜色值被改为"Red"
。 -
第二行创建了一个新对象(颜色值为
"Green"
)。新对象位于内存位置200。后续在balloon
变量上执行的任何方法都针对内存位置200的对象进行操作,不会影响内存位置100的对象。新的balloon
变量覆盖了第1行创建的引用,第1行中创建的balloon
引用在此方法内不再可访问。 -
第三行更改了記憶體位置200的新
Balloon
對象的顏色值為"Blue"
,但不影響記憶體位置100的blue
引用的原始對象。這解釋了為什麼示例程序輸出的最後一行打印blue color value = Red
,這反映了從第1行的變化。
結論
在本文中,您了解了為什麼Java是按值傳遞。通過更多的Java教程繼續學習。
Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference