關于Java的參數(shù)傳遞悔雹,是一個老生常談的問題了复哆,引用傳遞、值傳遞傻傻的分不清楚是許多程序員經(jīng)常遇到的問題腌零,那么今天就來聊聊Java中的參數(shù)傳遞寂恬。
先來看個例子:
public static void main(String[] args) {
int[] arr = {3,4,5,6};
int num = 5;
changearr(arr);
changenum(num);
System.out.println("arr[0] = " + arr[0]);
System.out.println("num = " + num);
}
public static void changearr(int[] arr) {
arr[0] = 1;
}
public static void changenum(int num) {
num = 1;
}
結(jié)果:
arr[0] = 1
num = 5
分析
從上面代碼的運行結(jié)果不難發(fā)現(xiàn),在傳遞基本類型時莱没,方法內(nèi)部并不能改變方法外的變量初肉,而引用類型則會被改變。
那么Java倒底是用的值傳遞還是引用傳遞呢饰躲?
在《Head First Java》里面曾解釋過:
Java在調(diào)用方法牙咏,傳遞參數(shù)的時候,采用的是pass-by-copy的方法嘹裂,傳遞一份內(nèi)容的拷貝妄壶,即傳值。
所以說Java用的應該是值傳遞寄狼,那么為什么會出現(xiàn)上面的情況呢丁寄?
這就涉及到Java中的兩種數(shù)據(jù)類型了:引用類型和基本類型。
1.基本數(shù)據(jù)類型
Java中一共分為8種基本數(shù)據(jù)類型:byte泊愧、short伊磺、int、long删咱、float屑埋、double、char痰滋、boolean,其中byte摘能、short、int敲街、long是整型团搞。float、double是浮點型,char是字符型,boolean是布爾型多艇。
上面這段話相信學過Java的人都看過逻恐,隨便一本講Java的書都應該有。
2.引用數(shù)據(jù)類型
Java中有3種引用類型:class類 、interface接口 梢莽、array數(shù)組。
基本類型和引用類型的區(qū)別
下面關鍵點來了奸披,上面兩種數(shù)據(jù)類型的區(qū)別在哪呢昏名?
基本數(shù)據(jù)類型的變量是存儲在棧內(nèi)存中,而引用類型變量存儲在棧內(nèi)存中阵面,保存的是實際對象在堆內(nèi)存中的地址轻局,實際對象其實是在堆上的。
啥是堆和棧样刷?如果這都區(qū)分不清楚的話仑扑,建議還是去看看JVM內(nèi)存相關的知識,這里就不詳細說了置鼻。
看到這里應該能明白為什么會出現(xiàn)例子中的情況了吧镇饮。
首先,Java確確實實是傳值(pass-by-value)的箕母,在上面的例子里储藐,傳過去的確確實實也是一個值的copy,但是引用型(Reference Type)變量里面存放的值是對象的地址嘶是,那么傳遞過去的就是原對象的地址钙勃。也就是說,在方法中的數(shù)組指向的地址和原數(shù)組指向的地址是一樣的聂喇,而我們對數(shù)組操作時是操作數(shù)組指向的地址段中的內(nèi)容辖源,方法內(nèi)和方法外操作的是同一段內(nèi)存,那么自然改變也是同步的希太。
好像還是不大好理解克饶,看看《Head First Java》里面的電視機和遙控器的例子吧:
引用類型的對象就相當于一個電視機和遙控器,我們傳遞的時候是復制了一個一摸一樣的遙控器誊辉,因此彤路,盡管新舊兩個遙控器不是同一個對象,但是兩個遙控器都可以控制電視芥映,新遙控器換臺洲尊,電視機一樣會響應。
而基本類型的對象則相當于只有一個遙控器奈偏,我們傳遞的時候依舊是復制了一個一摸一樣的遙控器坞嘀,就算我們把新的遙控器拆掉,原來的遙控器也不會受到絲毫影響惊来。