引言
這個(gè)問(wèn)題比較基礎(chǔ),但是也有必要一提,全當(dāng)再?gòu)?fù)習(xí)一下吧必指。java里到底是值傳遞還是引用傳遞呢囊咏?如果是引用傳遞,好像也能解釋清楚"一個(gè)對(duì)象被傳入方法,方法中對(duì)對(duì)象屬性的修改會(huì)影響外層對(duì)象的值"。如果是值傳遞也有點(diǎn)說(shuō)不過(guò)去,如果在方法內(nèi)對(duì)這個(gè)對(duì)象重新初始化塔橡,卻對(duì)外層對(duì)象沒(méi)有任何影響梅割。帶著這幾個(gè)疑問(wèn)來(lái)看一看吧!
測(cè)試一下
public static void main(String[] args) {
int index = 1;
change(index);
System.out.println(index);
}
private static void change(int index) {
index = 3;
}
結(jié)果是1
,因?yàn)閭魅氲氖腔绢愋妥兞?方法內(nèi)的index=3
賦值操作不影響外層的輸出。那么換成引用類型呢葛家?
public static void main(String[] args) {
Inner inner = new Inner();
inner.setId(32);
inner.setUserName("jerrik");
printDetail(inner);
System.out.println(inner);
}
private static void printDetail(Inner inner) {
inner.setId(27);
}
結(jié)果是27 - jerrik
户辞,無(wú)論是值傳遞還是引用傳遞都可以解釋。再來(lái)一個(gè)測(cè)試程序驗(yàn)證一下:
public static void main(String[] args) {
Inner inner = new Inner();
inner.setId(32);
inner.setUserName("jerrik");
change(inner);
System.out.println(inner);
}
private static void change(Inner inner) {
inner = new Inner();
}
這里輸出:32 - jerrik
惦银。這下可以解釋清楚了,如果inner對(duì)象作為值傳遞的參數(shù),方法內(nèi)將該inner置空,則應(yīng)該輸出空值
才對(duì),所以可以得出結(jié)論:java并不是使用對(duì)象的值作為傳遞的
。如果是引用傳遞,則是將外層引用重新指向了一個(gè)新地址,也應(yīng)該輸出空值
末誓。那到底傳遞是什么呢扯俱?
權(quán)威依據(jù)
《JAVA核心技術(shù)》中講到"java程序設(shè)計(jì)語(yǔ)言總是采用值調(diào)用。也就是說(shuō)喇澡,方法得到的是所有參數(shù)值的一個(gè)拷貝迅栅,方法不能修改傳遞給它的任何參數(shù)變量的內(nèi)容。"
說(shuō)明傳遞的并不是對(duì)象的值,而是重新創(chuàng)建了一份拷貝進(jìn)行傳入,那到底是對(duì)象的拷貝還是引用的拷貝呢晴玖?如果是對(duì)象的拷貝,在堆中則會(huì)存在兩個(gè)Inner對(duì)象,那么對(duì)拷貝出來(lái)的對(duì)象進(jìn)行設(shè)值不會(huì)影響外層,但是和事實(shí)剛好相反,所以排除是對(duì)象的拷貝读存。那么就只能是棧內(nèi)存地址的拷貝,使它們同時(shí)指向堆內(nèi)的同一個(gè)地址,所以可以通過(guò)set
來(lái)修改外層對(duì)象的值,即使通過(guò)inner = new Inner();
也只會(huì)使這份拷貝出來(lái)的新地址指向這個(gè)新對(duì)象,而不會(huì)影響原來(lái)的對(duì)象。
結(jié)論
當(dāng)發(fā)生方法調(diào)用的時(shí)候,傳入的是外層對(duì)象棧內(nèi)存地址的一份拷貝,也是一個(gè)數(shù)值呕屎,指向的還是同一塊堆內(nèi)存让簿,所以java采用的不是引用傳遞而是值傳遞。最后秀睛,本文是根據(jù)個(gè)人理解整理的,如有勘誤請(qǐng)多諒解!