Java中只有按值传递,没有按引用传递!
今天,我在一本面試書上看到了關于java的一個參數傳遞的問題:
原文地址:http://guhanjie.iteye.com/blog/1683637?
寫道 java中對象作為參數傳遞給一個方法,到底是值傳遞,還是引用傳遞??我毫無疑問的回答:“引用傳遞!”,并且還覺得自己對java的這一特性很是熟悉!
結果發現,我錯了!
答案是:
值傳遞!Java中只有按值傳遞,沒有按引用傳遞!
?
回家后我就迫不及待地查詢了這個問題,覺得自己對java這么基礎的問題都搞錯實在太丟人!
?
綜合網上的描述,我大概了解了是怎么回事,現在整理如下,如有不對之處望大神提出!
?
先來看一個作為程序員都熟悉的值傳遞的例子:
?
Java代碼???
答案顯而易見,調用函數changeValue()前后num的值都沒有改變。
?
由此做一個引子,我用圖表描繪一個值傳遞的過程:
?
num作為參數傳遞給changeValue()方法時,是將內存空間中num所指向的那個存儲單元中存放的值,即"5",傳送給了changeValue()方法中的x變量,而這個x變量也在內存空間中分配了一個存儲單元,這個時候,就把num的值5傳送給了這個存儲單元中。此后,在changeValue()方法中對x的一切操作都是針對x所指向的這個存儲單元,與num所指向的那個存儲單元沒有關系了!
自然,在函數調用之后,num所指向的存儲單元的值還是沒有發生變化,這就是所謂的“值傳遞”!值傳遞的精髓是:傳遞的是存儲單元中的內容,而非地址或者引用!
?
接下來,就來看java中的對象參數是怎么傳遞的:
同樣,先給出一段代碼:
Java代碼???
?答案應該大家都心知肚明:
第一次顯示:“Jack”
第二次顯示:“Rose”
?
方法用了一個對象參數,該對象內部的內容就可以改變,我之前一直認為應該是該對象復制了一個引用副本給調用函數的參數,使得該方法可以對這個對象進行操作,其實是錯了!
http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html 寫道 Java 編程語言只有值傳遞參數。當一個對象實例作為一個參數被傳遞到方法中時,參數的值就是該對象的引用一個副本。指向同一個對象,對象的內容可以在被調用的方法中改變,但對象的引用(不是引用的副本)是永遠不會改變的。??
為什么這里是“值傳遞”,而不是“引用傳遞”?
我還是用圖表描繪比較能解釋清楚:
?
?
主函數中new 了一個對象Person,實際分配了兩個對象:新創建的Person類的實體對象,和指向該對象的引用變量person。
【注意:在java中,新創建的實體對象在堆內存中開辟空間,而引用變量在棧內存中開辟空間】
正如如上圖所示,左側是堆空間,用來分配內存給新創建的實體對象,紅色框是新建的Person類的實體對象,000012是該實體對象的起始地址;而右側是棧空間,用來給引用變量和一些臨時變量分配內存,新實體對象的引用person就在其中,可以看到它的存儲單元的內容是000012,記錄的正是新建Person類實體對象的起始地址,也就是說它指向該實體對象。
這時候,好戲上臺了:
調用了changeName()方法,person作為對象參數傳入該方法,但是大家特別注意,它傳入的是什么!!!person引用變量將自己的存儲單元的內容傳給了changeName()方法的p變量!也就是將實體對象的地址傳給了p變量,從此,在changeName()方法中對p的一切操作都是針對p所指向的這個存儲單元,與person引用變量所指向的那個存儲單元再沒有關系了!
回顧一下上面的一個值傳遞的例子,值傳遞,就是將存儲單元中的內容傳給調用函數中的那個參數,這里是不是異曲同工,是所謂“值傳遞”,而非“引用傳遞”!!!
?
那為什么對象內部能夠發生變化呢?
那是因為:p所指向的那個存儲單元中的內容是實體對象的地址,使得p也指向了該實體對象,所以才能改變對象內部的屬性!
這也是我們大多數人會誤以為是“引用傳遞”的終極原因!!!
總結
以上是生活随笔為你收集整理的Java中只有按值传递,没有按引用传递!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式:回调模式
- 下一篇: 阿里Java面试题剖析:为什么使用消息队