Java只有值傳遞
簡書同步 Java只有值傳遞
為什麼寫這篇文章
網路上說這個問題的文章非常多,但是真的能說明白的目前我沒有找到。而且很大一部分是錯誤的,所以這裡試著用通俗易懂的方式把這個話題說清楚,也希望大家對這個問題有個更好的理解
基本資料型別 值傳遞
基本資料型別使用值傳遞
這個基本沒有什麼問題。這個沒有誤解,先撇開基本型別值傳遞不談了。
思考
- 如果引數是引用型別,就是引用傳遞?這句話對嗎?
很多人以為傳遞的是物件的引用所以是引用傳遞,理解的誤區就在這
先丟擲結論 Java 沒有引用傳遞 官方說的 而且絕對正確
- Java 沒有引用傳遞
- Java 傳遞物件 確實是傳遞物件的引用。更確切的說是傳遞的物件引用的副本。
- Java傳遞的是引用的副本。而不是引用本身,所以引用沒有傳遞,所以這個不叫引用傳遞。
什麼才叫引用傳遞? 為什麼那麼多人有誤解
如果把引用也看做一個物件。那麼引用傳遞的意思就是把這個引用物件傳遞給這個方法。而不是傳遞這個引用的副本。Java裡傳遞的就是引用的副本,雖然這個副本也是引用。但是在Java中只能說是傳遞物件的引用,而不能叫引用傳遞。
首先這不是一個文字遊戲,咬文嚼字,也沒有意義。
因為有很多語言有引用傳遞,所以引用傳遞的概念是明確的。而且具體內容也是明確的。跟Java的物件傳遞是有本質區別的。
如何理解什麼叫傳遞引用本身呢?
這裡因為Java沒有引用傳遞,所以先用C++ 簡單解釋一下,程式碼仿照Java程式碼
class TV{
public String name;
}
class User{
public TV getTV(&TV tv){//C++可以這樣來傳遞引用 而不是物件引用的副本 &TV 代表傳入一個引用
//這裡傳遞一個TV 的引用 這個引用跟Java的引用是有區別的
tv = new TV("xiaomi");//我修改為了小米牌的
//如果在Java裡 這句話不會影響傳入的tv 但是 C++ 會影響
}
}
public static void main(String[] args) {
TV tv = new TV("shape"); // 這個是夏普牌的電視
User son = new User();
// User father = new User();
son.getTV(tv);
System.out.println(" TV is " + tv);
// 我這是用Java寫的虛擬碼 如果在Java裡 這裡列印的是shape 但是C++ 這個地方已經指向了xiaomi
// 這就是引用傳遞和非引用傳遞的本質區別了
}
引用傳遞是真的把這個引用傳遞給了這個方法,這個方法修改引用的值,會改變傳入的引用本身指向的值,這個傳遞叫做引用傳遞而Java只是傳遞引用的副本,所有這個不能叫引用傳遞。在Java裡只能叫傳遞了物件的引用。而本質確是傳遞了物件的引用的副本。
最好理解的引用傳遞
這裡用遙控器和電視機來簡單理解什麼是引用傳遞。
一臺電視機
一個遙控器
這個遙控器可以操作電視機。
假設我們有一個電視機的物件
TV tv = new TV(); //建立了一個新的電視機物件。
這裡的tv 是指向這個物件的 遙控器。 是一個指向電視機的引用。
這裡應該很好理解。我只是把這個引用換了 一個概念而已
tv.changeChannel("CCTV5");// 通過遙控器調整頻道。
tv.changeChannel("CCTV1");// 通過遙控器調整頻道。
tv.changeChannel("CCTV9");// 通過遙控器調整頻道。
這裡也很好理解
現在我爸想看湖南衛視,他跟我說把遙控器給他。
Father{
public TV getTV(TV tv);
}
Father father = new Father();
TV fatherTV = father.getTV(tv);
fatherTV.changeChannel("HNTV");
問題就在這裡了。
Java中傳遞的物件的引用對吧?其實這句話是錯的。Java中傳遞的是物件的引用的副本。
只是我們為了方便。直接說傳遞物件的引用,因為引用的副本也是物件的引用
這裡還沒有很繞,還是好理解的。
那麼 在 電視機 和遙控器 的概念裡。這個傳遞是怎麼傳遞的呢
有兩種方式。
第一種,我有一個遙控器直接給了 Father;
第二種,我新買了一個能遙控這臺電視的遙控器給了Father。
第一種 是 我把遙控器傳遞給了 Father
第二種 是 我拿了另一個遙控器給了 Father
這就是本質的區別。
第一種就是 引用傳遞。是遙控器真的傳遞給了Father。遙控器代表引用,所以是引用傳遞給了Father
而第二種 就是值傳遞。只是給了他一個新的遙控器。而我的遙控器沒有傳遞。所以不能叫 遙控器傳遞 也就不能叫 引用傳遞。
用文字理解就是 這個概念。
總結
- Java 沒有引用傳遞
- Java傳遞的引用的副本。而不是引用本身,所以引用沒有傳遞,所以這個不叫引用傳遞。
- Java傳遞的是物件的引用,更確切的說是傳遞的物件引用的副本。
理解
引用傳遞就是引用本身,傳遞給方法,所以叫引用傳遞。而Java傳遞的是引用物件的副本。所以Java的引用型別的引數傳遞不能叫引用傳遞。
Java引用物件的傳遞,傳遞的是引用型別的副本,或者說是引用型別的值,所以說Java是值傳遞,而不是引用傳遞。
其實這個概念確實非常繞,但是理解了之後對Java為什麼不能實現 swap(Object &a, Object &b)還是有幫助的
就是因為Java沒有引用傳遞,所以才無法實現swap 函式。
相關文章
- 為什麼說Java中只有值傳遞。Java
- 你們不要再吵了! Java只有值傳遞..Java
- java值傳遞Java
- Java的值傳遞和引用傳遞Java
- Java - 是值傳遞還是引用傳遞Java
- 解惑4:java是值傳遞還是引用傳遞Java
- Java 從陣列來看值傳遞和引用傳遞Java陣列
- 值傳遞和引用傳遞
- Java是值傳遞還是引用傳遞,又是怎麼體現的Java
- 按值傳遞
- 快速搞懂值傳遞與引用傳遞
- JavaScript的值傳遞和引用傳遞JavaScript
- 這一次,徹底解決Java的值傳遞和引用傳遞Java
- Day30--值傳遞和引用傳遞
- go 值傳遞和地址傳遞的例子Go
- 面試官:兄弟,說說Java到底是值傳遞還是引用傳遞面試Java
- 這一次,讓你徹底理解Java的值傳遞和引用傳遞!Java
- JS的方法引數傳遞(按值傳遞)JS
- [精]--這一次,讓你徹底明白Java的值傳遞和引用傳遞!Java
- golang工作筆記(二)值傳遞與引用傳遞Golang筆記
- 關於值傳遞和引用傳遞的解釋
- python的賦值傳遞Python賦值
- JavaScript之按值傳遞JavaScript
- C#|.net core 基礎 - 值傳遞 vs 引用傳遞C#
- AbilitySlice之間的傳遞值
- html、php和js值的傳遞(使用ajax進行傳遞)HTMLPHPJS
- Java傳參傳值Java
- 面試官問:Go 中的引數傳遞是值傳遞還是引用傳遞?面試Go
- 用畫小狗的方法來解釋Java中的值傳遞Java
- JavaScript 是如何工作的:JavaScript 的共享傳遞和按值傳遞JavaScript
- C#程式設計引用型別和值型別 以及引用傳遞和值傳遞C#程式設計型別
- Vue父子之間的值傳遞Vue
- 一切皆按值傳遞
- Python的函式引數傳遞:傳值?引用?Python函式
- 188W+程式設計師關注過的問題:Java到底是值傳遞還是引用傳遞?程式設計師Java
- 關於String是值傳遞還是引用傳遞,talk is cheap, just show codes
- 微信小程式中的值傳遞微信小程式
- JavaScript 獲取 url 傳遞引數值JavaScript