无论是深拷贝还是浅拷贝,都需要实现 Cloneable 接口,并覆写 clone() 方法。
浅拷贝
@Override
public Object clone() {
//浅拷贝
try {
// 直接调用父类的clone()方法
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
- 改变变量值,不会影响其他内容。
对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象 - 改变引用类型的值,会影响其他内容
因为引用类型是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,它们指向了同一内存空间。改变其中一个,会对另外一个也产生影响。
PS:对象拷贝和浅拷贝不同
- 浅拷贝:
Student studentB = (Student) studentA.clone()
这里studentA 和StudentB对象指向的地址是不同的
- 拷贝对象
Student studentB = studentA
这里studentA 和StudentB对象指向的地址是相同的
可见,对象拷贝后没有生成新的对象,二者的对象地址是一样的;而浅拷贝的对象地址是不一样的。
所以:
对于拷贝对象来说,对象的地址不会改变
浅拷贝:
- 对象当中的引用类型的地址不会改变。因此会导致不同对象改变引用值之后,引用类型的内容会改变。
- 对象当中变量的改变不会受到影响
深拷贝
(1) 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。
(2) 对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。
(3) 对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法,进而实现了对象的串行层层拷贝。
(4) 深拷贝相比于浅拷贝速度较慢并且花销较大。
/**
* 重写clone()方法
* @return
*/
@Override
public Object clone() {
//深拷贝
try {
// 直接调用父类的clone()方法
Student student = (Student) super.clone();
student.subject = (Subject) subject.clone();
return student;
} catch (CloneNotSupportedException e) {
return null;
}
}
reference:java的深拷贝与浅拷贝