java中有引用传递吗(一)

首先要说明,什么是值传递和引用传递,这种说法针对的是实参和形参而言的,如果有c/c++基础的话就很容易明白,如果参数是值,那么在形参的方法内部对参数做改变,是不会影响到实参的。而如果参数是一个引用,那么实参会被形参的修改所改变。值传递没有什么好说的,(当然在总结的时候我会结合java的堆栈模型详细分析值传递和引用传递。)
如果引用传递没听懂,我们来看一个直观的程序就可以了。


参数传递.png

上图说明在传递引用类型时,方法内部修改其属性,会让其本身也被修改。在表现形式上,无疑是引用传递。
但事实真的如此吗,我们来看同样作为引用类型的String,在参数传递中的表现。如下图:

image.png

输出123,abc吗,不对,输出结果是123,123,有人可能说了,是你定义方式不对,写成new的形式才是引用类型,那我们在试一次。如下图:


image.png

最终结果依然是123,123。还有一种方式创建String对象是用StringBuilder,结果依然相同。
那会不会就是String的原因,它太特殊了,(String的确是特殊的,下一篇我就会写String的特殊性和它在参数传递的过程中发生了什么。)你就不能创建个普通的类来做传递吗,像第一个程序一样。
那么,如下图:


image.png

wow,如果按照c++的引用传递做类比,那第二个地址应该是打不出来的。那么我们可以的出一点结论:
如果修改的是引用类型中的一个属性,那么形参的修改是同时修改实参的。如果修改的是形参本身。(如上,把整个对象置null),那么是不会改变实参的。
实际上,java所谓的引用传递其实是传递一个值:引用的地址的复制。形参拿着这个地址指向和实参一致的堆内存。

如下图:


image.png

当形参修改堆内一个实例的一个属性时,并不会让形参的地址发生变化,因为属性在实例内部(如第一个程序)。
如下图:


image.png

但要是修改对象本身时,那是要在堆内新建一个实例的,形参内部的地址也将发生改变,指向新的地址。
如下图:


image.png

举个自认为形象的例子:
1.你有一个玩具,你朋友很喜欢,你就又买了一个一模一样的送给他,这是值传递,c++和java在这里是相同的(值传递只针对基本类型)。
2.你有自己家的钥匙,你借给了你的朋友,这是引用传递(c++),之后朋友用钥匙进你家门把电视砸了,那伤害自然是能反馈到你本体的,因为那是你的电视。
3.Java中所谓的引用传递是这样:你有自己家的钥匙,你复制的一把给了你的朋友,(即传递的是地址的副本),之后朋友用钥匙进你家门把电视砸了,那伤害自然也是能反馈到你本体的(第一个程序)。
4.现在你朋友要拿着钥匙拆你家了!(第四个程序),c++说,那你拆就拆吧,我没办法(引用传递,因为形参拿到了实参的引用),
java说,不行!我新建个房子给你拆。(值传递,形参只是拿到地址,只需要改变地址的指向即可),就偷偷把朋友的钥匙换成一个新的。
以上。下一篇分析String的特殊性。为什么它是一个引用类型,改变它值也不会反馈回去?

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容