integer是值傳遞還是引用傳遞_188W+程序員都關注的問題:Java到底是值傳遞還是引用傳遞?

 2023-12-10 阅读 28 评论 0

摘要:來源于公眾號沉默王二 ,作者沉默王二在逛 Stack Overflow 的時候,發現了一些訪問量像阿爾卑斯山一樣高的問題,比如說這個:Java 到底是值傳遞還是引用傳遞?訪問量足足有 188萬+,這不得了啊!說明有很多很多的程序員被這個

來源于公眾號沉默王二 ,

作者沉默王二

在逛 Stack Overflow 的時候,發現了一些訪問量像阿爾卑斯山一樣高的問題,比如說這個:Java 到底是值傳遞還是引用傳遞?訪問量足足有 188萬+,這不得了啊!說明有很多很多的程序員被這個問題困擾過。實話實說吧,我就是其中之一。

來回顧一下提問者的問題:

我一直認為 Java 是按引用傳遞的,但是我看一些博客上說不是的。我就納悶了,Java 到底是值傳遞還是引用傳遞?值傳遞和引用傳遞有什么區別呢?

如果你也曾被這個問題困擾過,或者正在被困擾,就請隨我一起來梳理一下問題的答案。打怪進階嘍!

01、值傳遞和引用傳遞

什么是值傳遞,什么是引用傳遞?我們需要先把這兩個定義搞清楚,才能搞清楚 Java 是按值傳遞還是按引用傳遞。

值傳遞(pass by value)是指在調用方法時將實參復制一份傳遞到方法中,這樣當方法對形參進行修改時不會影響到實參。
引用傳遞(pass by reference)是指在調用方法時將實參的地址直接傳遞到方法中,那么在方法中對形參所進行的修改,將影響到實參。

上面是比較官方的定義,讀起來不免生硬。在我看來,值傳遞和引用傳遞的關鍵區別有兩點:

1)調用方法時有沒有對實參進行復制。

2)方法內對形參的修改會不會影響到實參。

what?值傳遞和引用傳遞還沒有搞清楚,又來兩個新名詞:實參和形參。別急,別急。

02、實參和形參

實參和形參理解起來比值傳遞和引用傳遞容易的多,前者就好像是一元一次方程,后者就像是一元二次方程。

形參:定義方法名和方法體的時候使用的參數,目的是用來接收調用該方法時傳入的參數。
實參:在調用有參方法時傳入的參數,方法名后面的括號中的參數通常被稱為“實參”。

大家應該都寫過“hello world”程序了,就像下面這樣。

8bff365165bbe3b7af7871a1dc1dedc7.png

其中 args 就相當于是形參,而字符串“hello world”就相當于是實參。如果覺得這個例子不容易理解,那再來看一個。

194f1c18a1cc033f9bb1a802a667227d.png

其中“沉默王二”為實參;有參方法 sop(String name) 中的 name 為形參。形參就好像實參與被調用方法之間的一個橋梁,否則調用者沒法傳遞參數,被調用的方法無法接收參數。

03、基本類型是值傳遞的

Java 中的數據類型可以分為兩種,一種是基本類型,一種是引用類型。我相信大家在看本篇文章之前,就能夠達成這樣一個共識:基本類型是值傳遞的。這一點毫無疑問。

403d1783b7619cf142ae3efac1916fd7.png

上面這段代碼中,sop() 方法的實參 age 為 18,盡管 sop() 方法的形參被修改為 28,但并不會影響實參的值。這一點可以從輸出結果中加以證明。

具體的執行過程如下圖所示。

d921d865e0817675e778eac29e6d0cf4.png

04、引用類型是值傳遞嗎?

大家之所以不確定 Java 是值傳遞的還是引用傳遞的,原因就出在這個引用類型上面。單從字面的意思上就容易搞混:引用類型不是引用傳遞難道還是值傳遞?

dfcd8f5455531f19508824abe512f4c7.png

在 main() 方法中,我們通過 new 關鍵字創建了一個對象 cmower,并將其 name 屬性設置為“沉默王二”;然后將實參 cmower 傳遞給 sop() 方法,在 sop() 方法中將形參 cmower 的 name 屬性修改為“沉默王三”。輸出結果是什么樣子呢?

呀!實參 cmower 的屬性 name 竟然不是“沉默王二”而是“沉默王三”了!看看,看看,Java 不是值傳遞吧?

別急別急。我們在 main 方法中追加幾行代碼。

41cd9bfc454ed88b2422e718e288429c.png

old == cmower 會是 true 還是 false 呢?閉上眼睛想一想。如果實在是想不出,拋一枚硬幣吧,反正不是 true 就是 false。假如引用類型是引用傳遞的,根據引用傳遞的定義(形參的修改將會影響到實參),那么結果一定就是 false。

我們來看一下輸出結果:

0fc34e82ee0f2eb48e40e9d39475048b.png

true?開什么玩笑?

不好意思,沒有開玩笑。Java 的確是值傳遞的。只不過,引用類型在調用有參方法的時候,傳遞的是對象的引用,并不是對象本身。而對象的引用在傳遞的過程中并沒有發生改變,雖然對象本身發生了變化。可以通過下面這幅圖感受一下。

e4238d2d5e119c1ca1c10f7dbffbe008.png

這下理解了吧?

05、總結

來看下面這段代碼。

3dab7e5fd90c0c7f7532456a2ef8926b.png

age 是基本類型,所以值就直接保存在變量中;而 name 是引用類型,變量中保存的只是對象的內存地址,這種變量一般稱之為對象的引用。

基本類型作為參數被傳遞時肯定是值傳遞;引用類型作為參數被傳遞時也是值傳遞,只不過“值”為對應的引用。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/194334.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息