java中的浅克隆与深克隆详解
克隆的定义:
克隆是创建一个对象的副本,使得副本对象的状态和原始对象相同,但是它们是独立的实体,对副本对象的修改不会影响到原始对象。
浅克隆:浅克隆实际上是一种有缺陷的克隆,因为它并不完全满足上面克隆的定义。它得到的副本可能不是一个独立的实体。为什么这么说呢?下面详细解释一下。
浅克隆原理:
- 对于基本类型的属性,直接复制值
- 对于引用类型的属性,复制的是引用对象的地址
基于上述原理就导致一个问题,就是浅克隆改变引用类型的值,原对象的值也会跟着改变,会受到影响。因为如果复制的是地址,那么他们的这个相同属性共用同一个堆地址。所以浅拷贝有缺陷。
Object类的clone()方法。意思就是某一个对象调用这个方法,这个方法会复制一个一模一样的新对象,并返回。
想要调用clone()方法,必须让被克隆的类实现Cloneable接口。如我们准备克隆User类的对象,代码如下
public class User implements Cloneable{
private String id; //编号
private String username; //用户名
private String password; //密码
private double[] scores; //分数
public User() {
}
public User(String id, String username, String password, double[] scores) {
this.id = id;
this.username = username;
this.password = password;
this.scores = scores;
}
//...get和set...方法自己加上
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
这个Clone方法就是一个浅克隆,对于分数属性,它只会复制地址,指向同一个堆内存。
深拷贝:深拷贝可以理解为浅拷贝的递归。Java中定义的clone没有深浅之分,都是统一的调用Object的clone方法。为什么会有深克隆的概念?是由于我们在实现的过程中刻意的嵌套了clone方法的调用。也就是说深克隆就是在需要克隆的对象类型的类中全部实现克隆方法。