用过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中失败!
这是个悲伤的故事。。。