浅拷贝首先会创建一个新的对象,这个对象和原始对象属性值相同。如果原始对象是数值类型对象,那么拷贝的就是基本类型的值;如果拷贝的对象是引用类型的话,拷贝的就是原始对象的地址,可以说浅拷贝就相当于是一个指针指向被拷贝对象的地址。
①对于基础类型的成员对象,浅拷贝会以值传递的方式,直接将属性值赋值给新的对象。修改原始对象的成员或者修改新对象的成员,不会另外一方的值。
②对于引用类型,比如数组或者类对象,因为引用类型是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,它们指向了同一内存空间。改变其中一个,会对另外一个也产生影响。
实现浅拷贝对象的类,要实现Cloneable接口
测试类
运行结果
可以看出对新复制出对象的基本数据类型成员进行修改,并不会改变原有对象中的成员,但是对引用类型成员进行修改,则原始对象中的成员也会被改变。
浅拷贝结构图大致如下:
现在将
修改为
可以看到结果
可以看出,对象赋值仅仅是将引用赋值给了新的对象,这两个对象指向同一的内存地址,修改其中一个对象的成员,另一个也会随之修改。
浅拷贝拷贝的对象中的引用类型指向的是同一块堆内存地址。这会使我们修改拷贝对象内容时会有数据安全隐患。深拷贝,在拷贝引用类型成员变量时,为引用类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝。
①对于引用类型,深拷贝都会新建一个对象空间来存储这些拷贝的引用,这样就会使它们指向不同的内存地址改变其中一个,不会影响另外一个。
②对于有多层对象的,每个对象都需要实现 <code>Cloneable</code> 并重写 <code>clone()</code> 方法,进而实现了对象的串行层层拷贝
③由于得为每一个引用类型成员开辟新的空间,相比较于浅拷贝,深拷贝将会更加消耗内存空间,并且花费更多时间。
修改subject来,使其也实现<code>Cloneable</code> 并重写 <code>clone()</code>
重写student的clone方法,拷贝引用成员subject
测试结果
可以看出,深拷贝后,不管是基础数据类型还是引用类型的成员变量,修改后都不会影响原始对象
深拷贝的结构图大致如下: