摘要:有種流行的觀點(diǎn)說(shuō)的另外一個(gè)特殊之處在于,在方法調(diào)用傳參數(shù)時(shí),是按值傳遞的,其他普通對(duì)象是引用傳遞。然而這種說(shuō)法是大大錯(cuò)誤的,至少是完全誤解了值傳遞和引用傳遞的概念。方法調(diào)用傳參只有一種傳遞就是值傳遞。
上篇文章說(shuō)到Java的String是比較特殊的對(duì)象,它是不可變的。
有種流行的觀點(diǎn)說(shuō)String的另外一個(gè)特殊之處在于,在方法調(diào)用傳參數(shù)時(shí),String是按值傳遞的,其他普通對(duì)象是引用傳遞。
然而這種說(shuō)法是大大錯(cuò)誤的,至少是完全誤解了值傳遞和引用傳遞的概念。
值傳遞和引用傳遞的概念:
值傳遞在發(fā)生的時(shí)候會(huì)為callee參數(shù)新建一個(gè)變量,新的變量存儲(chǔ)的值與實(shí)參的值一致。
引用傳遞時(shí),callee并不為參數(shù)變量新建對(duì)象,而是直接使用caller里的實(shí)參變量。
舉例來(lái)說(shuō):
public static void main(String[] args) { Object obj = new Object(); PassValue(obj); } private static void PassValue(obj) { String s = obj.toString(); }
如果是值傳遞,main函數(shù)中的obj和PassValue方法中的o是兩個(gè)獨(dú)立的變量,只是他們的值相等。
如果是引用傳遞,main函數(shù)中的obj和PassValue方法中的o根本就是同一個(gè)變量。
如果文字看的有點(diǎn)暈,請(qǐng)看手畫圖:
Surface上畫的有點(diǎn)抽象,包容一下。
打個(gè)比方,我要給你傳遞一些悄悄話,我把信息放到一個(gè)變量給你————一個(gè)txt文檔。我和你之間有兩種方式:
你直接訪問(wèn)我們電腦,以后你看我電腦上的txt文檔————咱倆共享變量;
你也可以復(fù)制一份txt到你的電腦,以后你看你自己電腦上的那份txt文檔————你和我各用各的變量。
在代碼里,第一種方式就是引用傳遞,第二種就是值傳遞。
還是接著例子,我給你傳遞的txt有可能會(huì)有兩種形式:
直接在txt里寫著我要說(shuō)的話"我看好你喲";
在txt里只有一個(gè)url,url指向一個(gè)網(wǎng)站,網(wǎng)站里寫著"我看好你喲".
第一種形式就是傳遞基本類型參數(shù),第二張是傳遞引用類型參數(shù)。
所以,這里有四種組合,我們一一來(lái)看:
引用傳遞傳遞基本類型參數(shù)。你把txt文檔里的話改為可是我并不看好你啊,我看得到,因?yàn)槟愀牡氖俏译娔X上的txt文檔。
引用傳遞傳遞引用類型參數(shù)。你直接改txt里的url地址,或者你不改url,而且去改url指向的網(wǎng)站的內(nèi)容,我都能看到;
值傳遞傳遞基本類型參數(shù)。你把txt文檔里的話改為可是我并不看好你啊,我看不到,因?yàn)槟愀牡氖悄汶娔X上的那份txt。
值傳遞傳遞引用類型參數(shù)。你直接改txt里的url地址,我看不到,因?yàn)槟愀牡氖悄汶娔X上的那份txt。你改url指向的網(wǎng)站的內(nèi)容,我看的到。
對(duì)應(yīng)代碼里,當(dāng)傳遞參數(shù)為引用類型時(shí),例子中改url地址就是在callee中改變變量指向的堆的位置,即指向另一個(gè)對(duì)象;改url指向的內(nèi)容,即是改變量指向的那個(gè)對(duì)象的內(nèi)容。當(dāng)傳遞參數(shù)為基本類型參數(shù)時(shí),例子中改變txt文檔內(nèi)容,就是callee改變參數(shù)的值。
搞清楚概念了,怎么想都能把問(wèn)題想明白。
回到開頭的問(wèn)題,有人說(shuō)String特殊,特殊在哪?無(wú)非有人發(fā)現(xiàn)String在callee里沒法被改,但是其他普通引用類型對(duì)象可以在callee里被改動(dòng)?,F(xiàn)在我們可以說(shuō),這是廢話。因?yàn)镾tring是不可變類,它的內(nèi)容一經(jīng)創(chuàng)建再不能變,別說(shuō)你通過(guò)參數(shù)傳遞,你就是在主函數(shù)里,你照樣沒法改String對(duì)象的內(nèi)容。所以String在callee中無(wú)法被改動(dòng)和參數(shù)傳遞方式壓根沒有關(guān)系,這是String的不可變性問(wèn)題,完全兩碼事。
可以看出來(lái),如果參數(shù)傳遞的是引用變量,那么無(wú)論是哪種傳遞方式,callee對(duì)對(duì)象內(nèi)容的改動(dòng),對(duì)caller都是可見的。除非你這對(duì)象壓根不能改。
Java方法調(diào)用傳參只有一種傳遞就是值傳遞。這并沒有道理可講,實(shí)現(xiàn)如此。
參考:
[1] https://en.wikipedia.org/wiki...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77082.html
摘要:我們?cè)谔幮聞?chuàng)建了一個(gè)并將其引用在處傳給了方法的參數(shù)該方法內(nèi)部引用在處被重新賦值。如果是引用傳遞,那么引用在處已經(jīng)被指向了新的輸出應(yīng)該為才對(duì),事實(shí)上是怎樣的呢事實(shí)上輸出了也就是說(shuō)方法改變了傳入引用所指對(duì)象的值。此處注意,并非將重新分配,而是。 我們來(lái)看一個(gè)新手甚至寫了多年Java的朋友都可能不是十分確定的問(wèn)題: 在Java方法傳參時(shí),究竟是引用傳遞還是值傳遞? 為了說(shuō)明問(wèn)題, 我給出一個(gè)...
摘要:引用泛型除了方法因不能使用外部實(shí)例參數(shù)外,其他繼承實(shí)現(xiàn)成員變量,成員方法,方法返回值等都可使用。因此,生成的字節(jié)碼僅包含普通的類,接口和方法。 為什么要使用泛型程序設(shè)計(jì)? 一般的類和方法,只能使用具體的類型:要么是基本類型,要么是自定義類的對(duì)應(yīng)類型;如果要編寫可以應(yīng)用于多種類型的代碼,這種刻板的限制對(duì)代碼的束縛就會(huì)很大。----摘自原書Ordinary classes and meth...
摘要:它對(duì)數(shù)組和對(duì)象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲(chǔ)在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時(shí)成為的副本。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可...
摘要:它對(duì)數(shù)組和對(duì)象使用按值傳遞,但這是在的共享傳參或拷貝的引用中使用的按值傳參。例如在這里,變量和值在執(zhí)行期間存儲(chǔ)在堆棧中。返回值這是可選的,函數(shù)可以返回值,也可以不返回值。變量被推入堆棧,從而在執(zhí)行時(shí)成為的副本。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 22 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可...
摘要:接下了,我們調(diào)用方法,來(lái)嘗試改變的值以此驗(yàn)證中的傳值方式。我們將作為實(shí)參傳給方法,形參來(lái)接受這個(gè)實(shí)參,在這里就體現(xiàn)出了兩種傳參方式的不同。中只有值傳遞這一種方式,只不過(guò)對(duì)于引用類型來(lái)說(shuō),傳遞的參數(shù)是對(duì)象的引用罷了。 前言 這幾天在整理java基礎(chǔ)知識(shí)方面的內(nèi)容,對(duì)于值傳遞還不是特別理解,于是查閱了一些資料和網(wǎng)上相關(guān)博客,自己進(jìn)行了歸納總結(jié),最后將其整理成了一篇博客。 值傳遞 值傳遞是指...
閱讀 1917·2021-11-24 11:16
閱讀 3265·2021-09-10 10:51
閱讀 3217·2021-08-03 14:03
閱讀 1272·2019-08-29 17:03
閱讀 3253·2019-08-29 12:36
閱讀 2239·2019-08-26 14:06
閱讀 502·2019-08-23 16:32
閱讀 2695·2019-08-23 13:42