關於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