幾個重要概念
實參、形參segmentfault
形式參數:定義函數名和函數體時候使用的參數,目的用來接收調用該函數時傳入的參數ide
實際參數:在調用有參函數時,主調函數與被調函數之間有數據傳遞關係。實際參數是調用有參方法的時候真正傳遞的內容。函數
public void tes(String name){ // 形式參數 name
System.out.println(name);
}學習
public static void main(String[] args) {
Test test = new Test();
test.tes("caijicoder"); // 實際參數 caijicoder
}this
值類型、引用類型:lua
值類型就是基本數據類型,8 種基本類型除外的數據類型都是引用類型。url
兩種類型分別表示兩種內存分配方式。一個值類型數據直接在棧上分配,存儲所包含的值,其值就表明數據自己。一個引用類型指向的數據在堆上分配,引用類型的值是這個堆上數據的地址。.net
int num = 10;
String str = "hello";
num 是基本類型(值類型),值就直接保存在變量中。
str 是引用類型,變量中保存的只是實際對象的地址(0x10),而不是 Hello 這個字符串。設計
值傳遞、引用傳遞:code
值傳遞(pass by value):指在調用函數時,將實參複製一份傳遞到函數中,形參接收到的內容實際上是實參的一個拷貝,函數對形參的修改並不會影響到實參
引用傳遞(pass by reference):指在調用函數時,將實參的地址直接傳遞到函數中,在函數中對參數的修改將會影響到實參
值傳遞和引用傳遞屬於函數調用時參數的求值策略(Evaluation Strategy),這是對調用函數時,求值和傳值的方式的描述,並不指傳遞的內容的類型。
也就是說,傳遞內容的類型是值類型仍是引用類型(地址),與值傳遞、引用傳遞無關,並不能說傳入的參數類型是值類型就是值傳遞。
接下來重點!!!
對於值傳遞,不管是值類型仍是引用類型,都會在調用棧上建立一個副本:
對於值類型而言,這個副本就是整個原始值的複製,對這個副本的操做,不影響原始值的內容。
對於引用類型而言,其副本也只是這個引用的複製,指向的仍然是同一個對象。因此對副本的操做,會影響原始值。
爲何 Java 只有值傳遞,但 C# 既有值傳遞,又有引用傳遞,這種語言設計有哪些好處? - Hugo Gu的回答 - 知乎
一個實例
定義 Person 類
public 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
public class Main {
private int X = 123;
public void updateVlue(int value){ // 傳入基本數據類型
value = value + 1;
System.out.println("變量value: "+value);
}
public void updateObject(Person person){ // 傳入引用類型
Person E = person;
E.setAge(21);
}
public void swapObject(Person A,Person B){ // 傳入引用類型
Person C = A;
A = B;
B = C;
}
public static void main(String[] args) {
// 例子 1
Main main = new Main();
int X = 1;
main.updateVlue(X);
System.out.println("X 的值:"+X); // X = 1
// 例子 2
Person A = new Person("張三",20);
main.updateObject(A);
System.out.println("A: "+A.toString()); // A: Person{name='張三', age=21}
// 例子 3
Person C = new Person("C",10);
Person D = new Person("D",15);
main.swapObject(C,D);
System.out.println("C: "+ C.toString()); // C: Person{name='C', age=10}
System.out.println("D: "+ D.toString()); // D: Person{name='D', age=15}
}
}
例子1:函數傳入基本數據類型(值類型參數),因爲 value 是 X 的一個副本,對 value 進行操做,並無改變原來實參的值。
例子2:函數傳入引用類型參數,改變了原來的值。因爲值傳遞的緣故,傳入引用類型的參數時,其值是這個地址的拷貝,指向的仍然是同一個對象,因此發生了改變。這是值傳遞帶來的效果,與傳入的對象是值類型或者引用類型沒有關係!
例子3:函數傳入引用類型,若是 Java 是引用傳遞, 那麼 swapObject(Person A,Person B) 中的形參 A,B 接收的就是 C 和 D 的地址,對 A,B 進行交換應該能成功的,事實上 C 和 D 並無交換,這從反面證實了 Java 不是引用傳遞。
————————————————
版權聲明:本文爲CSDN博主「愛學習的小肥豬」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/heima20...