美文网首页
浅谈Java参数传递机制、浅复制(shadow copy)、深复

浅谈Java参数传递机制、浅复制(shadow copy)、深复

作者: john_leventon | 来源:发表于2018-10-25 22:06 被阅读0次

                                                                    

1、参数传递机制

          参数传递机制分为引用传递值传递。引用传递就是将变量的内存地址(对于Java来说,这里说堆地址更为贴切)直接传递给方法,值传递就是将变量复制一份再传递给方法。值类型如基本数据类型传递给方法的是值的拷贝而不是实际的存储值变量的地址;而引用类型如对象引用传递给方法的是引用的拷贝。举个例子:

在上图代码中,我们声明了一个ReferenceA类,和一个int类型的变量value并初始化为0。可以看到change方法执行完后,变量value的值并没有被改变,但是ReferenceA类的对象的变量name的值却改变了。这是因为变量value传递给方法的只是value变量的值的拷贝,而refA则传递给方法的是对象refA的地址拷贝。这个拷贝的地址指向同一个对象。

但是,为什么说Java严格意义上来说是值传递而不是引用传递呢?

再看下面的例子:

在这个例子中,我们重载了change方法,我们试图在方法中改变实参refA的引用但是失败了。

所以方法并不能改变实参refA的引用,这是因为实参传递给方法的只是它的值的拷贝,而它的值就是refA对象的地址。所以在Java中只存在值传递

2、浅复制和深复制

在开发中,我们经常需要复制一个对象,使得复制后的对象改变不影响原来的对象。

看下面例子:

在这个例子中,我们声明了一个ClassA类并实现了Cloneable接口(它实际上是一个空接口,也称为标记接口标记这个类是可以被clone的)。

可以看到,我们成功复制了类ClassA类的对象classA1,改变对象classA11的name属性的值并不会影响到classA1对象的name属性。

再看一个例子:

在这个例子中,我们新声明了一个类ClassB,并在其中声明了一个成员变量classA。

可以发现,执行过classB1对象的clone()方法后我们获得了classB11这个克隆对象,当我们获取classB11中的classA变量并改变它的name属性时,发现classB1对象的classA变量的name属性也跟着改变了。也就是说我们克隆的classB11对象并不是完全的克隆,和本体还存在着关联,这就是浅复制。那么我们应该如何解除这种关系呢。

看下面例子:

在这个例子中,我们改写了ClassB中的clone方法。this.classA = (ClassA)classA.clone();

注意,当要复制的对象包含引用成员变量时,我们需要单独为这个引用成员变量单独进行clone,但是像String和基本数据类型的包装类如Double、Integer等的对象时不可变(immutable)对象,不需要单独进行clone。

相关文章

网友评论

      本文标题:浅谈Java参数传递机制、浅复制(shadow copy)、深复

      本文链接:https://www.haomeiwen.com/subject/dooctqtx.html