Java值傳遞和引用傳遞詳解

關於Java的值傳遞咱們知道:Java中基本類型做爲函數參數傳遞就是值傳遞,不管在函數中對傳進去的值作什麼操做,函數外面聲明的變量值都不會有什麼改變,而對象做爲函數參數傳遞進去則否則,爲何說否則呢,請看下面的代碼。
bash

下面的代碼中有三個函數,一個值傳遞,兩個引用傳遞app

package com.learn;

public class main {

    public static void change(int data){//值傳遞

        data = data+1;
    }
    public static void changeref(StringBuffer data){//引用傳遞1
        data = new StringBuffer("in changeref");
    }
    public static void changeref_2(StringBuffer data){//應用傳遞2
        data.append(" now changed");
    }
    public static void main(String[] args){

        int num = 10;
        System.out.println("num before changed: "+num);
        change(num);
        System.out.println("num after changed: "+num);


        StringBuffer str = new StringBuffer("outside");
        System.out.println("str before changed: "+str);
        changeref(str);
        System.out.println("str after changed: "+str);



        StringBuffer str_2 = new StringBuffer("outside");
        System.out.println("str_2 before changed: "+str_2);
        changeref_2(str_2);
        System.out.println("str_2 after changed: "+str_2);

    }


}
複製代碼


num before changed: 10
num after changed: 10
str before changed: outside
str after changed: outside
str_2 before changed: outside
str_2 after changed: outside now changed

Process finished with exit code 0
複製代碼

從代碼的運行結果能夠看到,不出意料的,咱們能夠看到基本類型int的值在通過函數操做後沒有任何變化,而一樣是引用傳遞str與str_2的結果卻徹底不一樣,這是爲何呢?jvm

回到代碼,能夠發現,changeref()函數中data直接指向了一個新的StringBuffer對象,通過此操做後函數外的str值並無任何改變,而changere_2()函數中data是日後追加了一段字符串,此操做後函數外的str_2值改變了。這是爲何呢?ide

在討論這個問題以前,先來討論一下什麼是值傳遞,什麼是引用。首先值傳遞的概念是將值複製一份傳入函數。而引用的概念就涉及到了jvm存儲模型,在jvm存儲模型中,基本類型都是直接存在Java虛擬棧中的,而對象都是新建在堆區,要想訪問位於堆區的對象,須要在Java虛擬棧中創建一個變量,它的值是:指向某個對象的地址,這個變量就是引用。函數

而在Java中並無真正的引用傳遞,一般所說的引用傳遞其實也是值傳遞。而在上面的代碼中,changeref()直接改變data的值是對複製過來的引用值進行改變,changeref_2()是對data指向的對象進行操做,換言之就是對堆中的對象進行改變,因此就出現這樣的結果。ui

相關文章
相關標籤/搜索