用過java和C++的同窗都知道在兩者中均有引用的概念。可是這兩個概念所表明的並不相同。 java
首先了解C++ 中引用的含義:「引用」即「別名」。C++中的引用表明的就是實際的存儲空間。對其進行操做就是對存儲空間進行操做。 數組
而在Java中的引用:能夠看作是C語言中的「指針」或者「地址」。對java中引用的屬性(即指針指向的存儲空間)進行操做纔是有效的。 數據結構
參考http://blog.csdn.net/wzy_1988/article/details/16886337: 函數
「 測試
對於概念有所瞭解了以後,主要來看看咱們常常容易困惑的地方——引用傳參: spa
1)Java引用做爲函數(方法)參數 .net
Java的方法參數只是傳值,引用做爲參數使用時,會給函數內引用的值的COPY,因此在函數內交換兩個引用參數是沒有意義的,由於函數交換的是參數的COPY值;可是在函數內改變一個引用參數的屬性是有意義的,由於引用參數的COPY值指向的對象和原引用指向的是同一個對象。 指針
2)C++引用做爲函數參數 對象
因爲C++引用傳進去的就是「別名」,因此在函數內對其進行的所有操做都將直接做用於實際的對象存儲空間上。 blog
產生這個困惑的緣由極可能是涉及到在函數(方法)中進行malloc(new)新的堆空間有關。其實這是一個比較有意思的問題。
咱們在新建一棵樹的時候,常常都會須要在新建函數(方法)中進行malloc(new)。固然,你可使用新建一個節點就做爲函數(方法)返回值進行返回。可是,通常人的思惟極可能是直接在函數裏面malloc(new),而後直接賦給傳入的表明樹的參數(T)。這種通常人的思惟方法大部分都是受到了嚴蔚敏《數據結構》的「荼毒」,而有沒有弄懂引用在Java和C++表明的不一樣意義而產生的錯誤。
誠然,咱們在C++中這樣來作是沒有問題的(參考嚴蔚敏《數據結構(C語言版)》P131),傳入了個BiTree &T而後(T = (BiTNode *)malloc(...)),很開心,測試一下OK了。
而後,在用Java寫樹的數據結構是仍是這麼幹,就出問題了。其主要的錯誤緣由是:Java中引用做爲傳參只是傳入個引用的COPY,這樣的在(T = new ...)以後,方法一結束,這個做爲引用的COPY就會被抹去,而在方法中的new對象因爲沒有引用(沒人指向它)也將做爲垃圾被回收掉。
咱們注意下其中涉及一個頗有趣的問題,這個問題是有關C語言中的malloc和JVM中的new的對象存儲空間的:
malloc和new產生的對象存儲都是發生在堆中的,而非棧。
而C++和Java的引用(包括引用COPY)都是在棧中的。
這麼說,其實它們的存儲結構是同樣的,可是卻因爲Java傳入的引用並不是真的引用,只是引用的COPY(有點像「狸貓換太子」),致使C++的樹實現方式可以實現,而相似地應用到Java中失敗!
這是個悲傷的故事。。。