值傳遞
"值傳遞"(Pass by Value)是指在呼叫方法時,將引數的值複製並傳遞給方法中的形參。這意味著方法接收的是原始資料的一個副本,而不是原始資料本身。以下是值傳遞的一些關鍵特點:
-
資料複製:當呼叫方法時,引數的值被複制到新記憶體區域(方法的棧空間)的形參中。
-
獨立性:方法內的形參和方法外的實參在記憶體中是獨立的。方法對形參的修改不會影響到實參。
-
基本資料型別:對於Java等語言中的原始資料型別(如
int
,double
,char
等),總是透過值傳遞。 -
不可變性:由於基本型別的不可變性,方法內對引數值的修改實際上並不改變原始資料。
-
記憶體效率:對於大型物件或陣列,值傳遞可能意味著複製大量資料,這可能不是最記憶體效率的方式。
-
物件引用:對於物件引用型別,值傳遞的是引用的副本,而不是物件本身。這意味著兩個引用指向同一個物件,但副本引用和原始引用是獨立的,改變副本引用不會影響原始引用。
-
副作用:值傳遞不保證方法內部對引數的修改對外部可見,除非引數本身是一個物件,並且方法修改了物件的內部狀態。
示例:
public class PassByValueExample {
public static void main(String[] args) {
int a = 10;
modifyValue(a);
System.out.println("Outside method: " + a); // 輸出不會改變,仍然是 10
}
public static void modifyValue(int value) {
value = 20; // 僅修改了傳入的副本,不影響原始變數
}
}
示例解釋:
- 在
main
方法中,我們有一個原始資料型別int a
,其值為 10。 - 呼叫
modifyValue
方法,並傳遞a
作為引數。 - 在
modifyValue
方法內,我們嘗試修改引數value
的值為 20。但這只是修改了value
的副本,原始變數a
的值不會改變。 - 列印
a
的值,輸出結果仍然是 10,表明方法內的修改沒有影響外部的a
。
值傳遞是大多數程式語言在引數傳遞時採用的機制,它有助於保護原始資料不被方法內部的修改影響。然而,對於物件引用,需要理解傳遞的是引用的副本,而不是實際的物件本身。
引用轉遞
引用傳遞(Pass by Reference)是指在呼叫方法時,傳遞的是物件的引用(或地址),而不是物件本身的複製。這意味著方法接收的是原始物件的引用,因此方法內部對物件所做的任何修改都會影響到原始物件。
引用傳遞的特點:
- 傳遞引用:方法接收的是物件引用的副本,但這個副本指向的是同一個物件。
- 共享物件:方法內對物件的修改會反映到原始物件上,因為它們共享同一個物件。
- 修改可見:方法內部對物件屬性的修改在方法外部是可見的。
- 物件不變:物件本身不會被複制,只有引用被傳遞,因此節省記憶體。
- 基本資料型別:對於基本資料型別(如
int
,double
等),大多數語言(包括Java)實際上是透過值傳遞。 - 物件型別:對於物件型別,傳遞的是引用的副本,但兩個引用指向同一個物件。
示例:
public class PassByReferenceExample {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
modifyPerson(person);
System.out.println("Outside method: " + person.getName() + ", " + person.getAge());
}
public static void modifyPerson(Person p) {
p.setName("Bob"); // 修改物件的屬性
p.setAge(40); // 修改物件的屬性
}
static class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
示例解釋:
- 在
main
方法中,建立了一個Person
物件person
。 - 呼叫
modifyPerson
方法,並傳遞person
作為引數。 - 在
modifyPerson
方法內,修改了傳入物件p
的name
和age
屬性。 - 這些修改會影響原始物件
person
,因為p
是對原始物件引用的副本。 - 列印
person
的資訊,輸出結果將反映方法內的修改:"Outside method: Bob, 40"。
注意:
- 在Java中,所有的引數傳遞都是透過值傳遞,包括物件的引用。因此,有時人們可能會混淆“引用傳遞”和“值傳遞”的概念。
- 當你傳遞一個物件的引用時,你實際上是傳遞了這個引用的副本,但這個副本指向同一個物件。因此,任何透過這個副本引用對物件所做的修改都會反映到原始物件上。