1. 程式人生 > 實用技巧 >Java 值傳遞和引用傳遞

Java 值傳遞和引用傳遞

目錄

結論

java中都是值傳遞,沒有引用傳遞。

如果引數型別是原始型別,那麼傳過來的就是這個引數的一個副本,也就是這個原始引數的值,這個跟之前所談的傳值是一樣的。如果在函式中改變了副本的值不會改變原始的值.。

如果引數型別是引用型別,那麼傳過來的就是這個引用引數的副本,這個副本存放的是引數的地址。如果在函式中沒有改變這個副本的地址,而是改變了地址中的值,那麼在函式內的改變會影響到傳入的引數。如果在函式中改變了副本的地址,如new一個,那麼副本就指向了一個新的地址,此時傳入的引數還是指向原來的地址,所以不會改變引數的值。

經典題目

class Person {
    int age = 10;
}

public class Main {
    public static void main(String[] args) {
        //case 1
        int var1 = 10;
        change(var1);
        System.out.println(var1);

        //case 2
        Person var2 = new Person();
        change(var2);
        System.out.println(var2.age);

        //case 3
        String var3 = "hello";
        change(var3);
        System.out.println(var3);

        //case 4
        Person var4 = new Person();
        changeNew(var4);
        System.out.println(var4.age);
    }

    private static void changeNew(Person var4) {
        var4.age = 20;
        var4 = new Person();//這裡更改了入參的地址
        var4.age = 10;
    }

    private static void change(String var3) {
        var3 = "world";
    }

    private static void change(Person person) {
        person.age = 20;
    }

    private static void change(int var1) {
        var1 = 20;
    }
}

在case 1中,入參是基本資料型別,所以修改的是副本的數值,不會影響原變數。

在case 2中,入參是引用物件,傳入的是引用變數的地址,所以修改了地址所對應的值,會影響原變數。這裡引用變數也包括陣列,對於陣列來說傳入的是第一個元素的地址。

在case 3中,入參是String,是一個引用型別,但是String是一個final類,所以傳入的是地址,對String的改變是重新開闢新的空間,而不是修改地址對應的內容,所以也不會修改原變數的值。

在case 4中,原理和case 3類似,也是開闢了新的地址空間,所以並沒有對原地址所對應的內容進行改動。

輸出為

10
20
hello
20