浅拷贝
基本概念
如果属性是基本类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
代码实现
实现对象拷贝的类,需要实现 Cloneable 接口,并覆写 clone() 方法。
public class Student implements Cloneable {//引用类型private Subject subject;//基础数据类型private String name;private int age;public Subject getSubject() {return subject;}public void setSubject(Subject subject) {this.subject = subject;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}/*** 重写clone()方法* @return*/@Overridepublic Object clone() {//浅拷贝try {// 直接调用父类的clone()方法return super.clone();} catch (CloneNotSupportedException e) {return null;}}@Overridepublic String toString() {return "[Student: " + this.hashCode() + ",subject:" + subject +",name:" + name + ",age:" + age + "]";}}
浅拷贝和对象拷贝的区别
Student studentB = (Student) studentA.clone() 换成了 Student studentB = studentA
对象拷贝后没有生成新的对象,二者的对象地址是一样的;而浅拷贝的对象地址是不一样的。
深拷贝
基本概念
- 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。
- 对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。
对于有多层对象的,每个对象都需要实现
Cloneable并重写clone()方法,进而实现了对象的串行层层拷贝。代码实现
public class Subject implements Cloneable {private String name;public Subject(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overrideprotected Object clone() throws CloneNotSupportedException {//Subject 如果也有引用类型的成员属性,也应该和 Student 类一样实现return super.clone();}@Overridepublic String toString() {return "[Subject: " + this.hashCode() + ",name:" + name + "]";}}
public class Student implements Cloneable {//引用类型private Subject subject;//基础数据类型private String name;private int age;public Subject getSubject() {return subject;}public void setSubject(Subject subject) {this.subject = subject;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}/*** 重写clone()方法* @return*/@Overridepublic Object clone() {//深拷贝try {// 直接调用父类的clone()方法Student student = (Student) super.clone();//调用subject的clone()方法student.subject = (Subject) subject.clone();return student;} catch (CloneNotSupportedException e) {return null;}}@Overridepublic String toString() {return "[Student: " + this.hashCode() + ",subject:" + subject + ",name:" + name + ",age:" + age + "]";}}
