Java中的值傳送

幾個重要概念
實參、形參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...

相關文章
相關標籤/搜索