一、浅拷贝
浅拷贝指的是按位复制对象属性,对于引用类型属性复制引用,对于基本类型属性则复制数据。
我们通过下面的例子来看一下浅拷贝做的操作:
浅拷贝当通过拷贝p1
生成对象p2
的后,我们发现两者的地址变换了,也就是说堆中分配的区域是不同,这个时候可以看出来两个确实不是同一个对象了。同时我们可以发现两个对象对于hand
对象的引用是相同。
可以预想的是,当我们改变hand
对象中fingerNum
的值的时候,两个Person
对象都会受到影响,因为在Java
中有两种传递,一种是引用传递,一种是值传递,此处表现的就是引用传递。
二、深拷贝
与浅拷贝相对,对于引用类型属性会新建引用,对于基本类型属性会复制数据
我们仅通过修改Person
对象的构造器即可以让其从浅拷贝变为深拷贝,从原来的直接传递引用变为创建对象并赋值,
从上图我们可以看到两个person
对象的地址不同,对应的hand
对象的地址也不同。
三、Cloneable
接口
Cloneable
接口位于lang
包下,这是一个空接口,实现该接口仅作为一个标记,表示对象可以调用从Object
对象继承而来的clone
方法,否则会抛出CloneNotSupportedException
异常。
实现了Cloneable
接口的对象可以通过调用clone
方法来复制一个自己,这里的clone
方法其实是进行了浅拷贝操作,我们可以通过实验来看一看:
该试验中有两个类,一个是Man
,另一个是Hand
,Man
包含了Hand
,同时Man
实现了Cloneable
接口并且重写了clone
方法。当我们通过调用clone
方法生成另一个实例对象之后,我们发现两个实例对象的地址不同,但是两个对象中包含的hand
地址是相同的,这符合上述所说的浅拷贝。
如果我们想通过clone
实现深拷贝呢?
其实道理是相通的,我们只要在clone
Man
对象的时候,把Hand
对象也clone
一下,这样就会由浅拷贝变为深拷贝,当然前提是Hand
对象也实现Cloneable
接口
四、总结
1.浅拷贝出来的对象是相互影响的,深拷贝出来的对象是独立的
2.Object
对象中的clone
方法进行的是浅拷贝
网友评论