Java只有值傳遞

為什么寫這篇文章

網(wǎng)絡(luò)上說這個(gè)問題的文章非常多,但是真的能說明白的目前我沒有找到。而且很大一部分是錯(cuò)誤的,所以這里試著用通俗易懂的方式把這個(gè)話題說清楚,也希望大家對(duì)這個(gè)問題有個(gè)更好的理解

基本數(shù)據(jù)類型 值傳遞

基本數(shù)據(jù)類型使用值傳遞
這個(gè)基本沒有什么問題。這個(gè)沒有誤解,先撇開基本類型值傳遞不談了。

思考

  • 如果參數(shù)是引用類型,就是引用傳遞?這句話對(duì)嗎?
    很多人以為傳遞的是對(duì)象的引用所以是引用傳遞,理解的誤區(qū)就在這

先拋出結(jié)論 Java 沒有引用傳遞 官方說的 而且絕對(duì)正確

  • Java 沒有引用傳遞
  • Java 傳遞對(duì)象 確實(shí)是傳遞對(duì)象的引用。更確切的說是傳遞的對(duì)象引用的副本。
  • Java傳遞的是引用的副本。而不是引用本身,所以引用沒有傳遞,所以這個(gè)不叫引用傳遞。

什么才叫引用傳遞? 為什么那么多人有誤解

如果把引用也看做一個(gè)對(duì)象。那么引用傳遞的意思就是把這個(gè)引用對(duì)象傳遞給這個(gè)方法。而不是傳遞這個(gè)引用的副本。Java里傳遞的就是引用的副本,雖然這個(gè)副本也是引用。但是在Java中只能說是傳遞對(duì)象的引用,而不能叫引用傳遞。

首先這不是一個(gè)文字游戲,咬文嚼字,也沒有意義。
因?yàn)橛泻芏嗾Z言有引用傳遞,所以引用傳遞的概念是明確的。而且具體內(nèi)容也是明確的。跟Java的對(duì)象傳遞是有本質(zhì)區(qū)別的。

如何理解什么叫傳遞引用本身呢?

這里因?yàn)镴ava沒有引用傳遞,所以先用C++ 簡單解釋一下,代碼仿照J(rèn)ava代碼
class TV{ 
    public String name; 
}
class User{
    public TV getTV(&TV tv){//C++可以這樣來傳遞引用 而不是對(duì)象引用的副本  &TV 代表傳入一個(gè)引用
         //這里傳遞一個(gè)TV 的引用 這個(gè)引用跟Java的引用是有區(qū)別的
         tv = new TV("xiaomi");//我修改為了小米牌的
         //如果在Java里 這句話不會(huì)影響傳入的tv 但是 C++ 會(huì)影響
    } 
    
}  
public static void main(String[] args) {
   TV tv = new TV("shape"); // 這個(gè)是夏普牌的電視
   User son = new User();
  // User father = new User();
   son.getTV(tv);
   System.out.println(" TV is " + tv);
   // 我這是用Java寫的偽代碼 如果在Java里 這里打印的是shape 但是C++ 這個(gè)地方已經(jīng)指向了xiaomi
   // 這就是引用傳遞和非引用傳遞的本質(zhì)區(qū)別了 
} 

引用傳遞是真的把這個(gè)引用傳遞給了這個(gè)方法,這個(gè)方法修改引用的值,會(huì)改變傳入的引用本身指向的值,這個(gè)傳遞叫做引用傳遞而Java只是傳遞引用的副本,所有這個(gè)不能叫引用傳遞。在Java里只能叫傳遞了對(duì)象的引用。而本質(zhì)確是傳遞了對(duì)象的引用的副本。


最好理解的引用傳遞

這里用遙控器和電視機(jī)來簡單理解什么是引用傳遞。

一臺(tái)電視機(jī)
一個(gè)遙控器
這個(gè)遙控器可以操作電視機(jī)。
假設(shè)我們有一個(gè)電視機(jī)的對(duì)象

TV tv = new TV();  //創(chuàng)建了一個(gè)新的電視機(jī)對(duì)象。
這里的tv 是指向這個(gè)對(duì)象的 遙控器。 是一個(gè)指向電視機(jī)的引用。
這里應(yīng)該很好理解。我只是把這個(gè)引用換了 一個(gè)概念而已
tv.changeChannel("CCTV5");// 通過遙控器調(diào)整頻道。
tv.changeChannel("CCTV1");// 通過遙控器調(diào)整頻道。
tv.changeChannel("CCTV9");// 通過遙控器調(diào)整頻道。
這里也很好理解

現(xiàn)在我爸想看湖南衛(wèi)視,他跟我說把遙控器給他。
Father{
    public TV getTV(TV tv);
}
Father father = new Father();
TV fatherTV = father.getTV(tv);
fatherTV.changeChannel("HNTV");
問題就在這里了。
Java中傳遞的對(duì)象的引用對(duì)吧?其實(shí)這句話是錯(cuò)的。Java中傳遞的是對(duì)象的引用的副本。
只是我們?yōu)榱朔奖?。直接說傳遞對(duì)象的引用,因?yàn)橐玫母北疽彩菍?duì)象的引用
這里還沒有很繞,還是好理解的。

那么 在 電視機(jī) 和遙控器 的概念里。這個(gè)傳遞是怎么傳遞的呢
有兩種方式。
第一種,我有一個(gè)遙控器直接給了 Father;
第二種,我新買了一個(gè)能遙控這臺(tái)電視的遙控器給了Father。

第一種 是 我把遙控器傳遞給了 Father  
第二種 是 我拿了另一個(gè)遙控器給了 Father

這就是本質(zhì)的區(qū)別。
第一種就是 引用傳遞。是遙控器真的傳遞給了Father。遙控器代表引用,所以是引用傳遞給了Father
而第二種 就是值傳遞。只是給了他一個(gè)新的遙控器。而我的遙控器沒有傳遞。所以不能叫 遙控器傳遞 也就不能叫 引用傳遞。
用文字理解就是 這個(gè)概念。

總結(jié)

  • Java 沒有引用傳遞
  • Java傳遞的引用的副本。而不是引用本身,所以引用沒有傳遞,所以這個(gè)不叫引用傳遞。
  • Java傳遞的是對(duì)象的引用,更確切的說是傳遞的對(duì)象引用的副本。

理解

引用傳遞就是引用本身,傳遞給方法,所以叫引用傳遞。而Java傳遞的是引用對(duì)象的副本。所以Java的引用類型的參數(shù)傳遞不能叫引用傳遞。

Java引用對(duì)象的傳遞,傳遞的是引用類型的副本,或者說是引用類型的值,所以說Java是值傳遞,而不是引用傳遞。

其實(shí)這個(gè)概念確實(shí)非常繞,但是理解了之后對(duì)Java為什么不能實(shí)現(xiàn) swap(Object &a, Object &b)還是有幫助的

就是因?yàn)镴ava沒有引用傳遞,所以才無法實(shí)現(xiàn)swap 函數(shù)。

問題溝通

上面內(nèi)容是個(gè)人總結(jié),雖然經(jīng)過多個(gè)版本,但是仍然需要完善
如果發(fā)現(xiàn)問題,希望大家指正,本人盡量及時(shí)修改,避免貽誤他人,萬分感謝
QQ 1400100300

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容