概念
浅克隆是指拷贝对象时仅仅拷贝对象中的基本类型变量(例如int,double,float,注意还有String),而不拷贝对象包含的引用指向的对象(即用户自定义的对象)。
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
用图解的方式来表示的话,就是:
在该图中,浅克隆后,自定义的Address对象没有克隆,而是与主体指向相同的对象,主体中的Address如果改变,克隆体中的Address也会随之改变。
而深克隆则是:
即克隆体与主体中的所有对象都不同,都不会互相影响。
实现方式
浅克隆的实现方式:(实现Cloneable接口)
public class Person implements Cloneable{
private String name;
private int age;
private Address address;
public Person() {
}
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("Hubei","Xiangyang");
Person p1 = new Person("zs",11,address);
Person p2 = (Person)p1.clone();
System.out.println("p1=>"+p1);
System.out.println("p2=>"+p2);
System.out.println("============修改地址后============");
address.setCity("Wuhan");
System.out.println("p1=>"+p1);
System.out.println("p2=>"+p2);
}
}
运行结果:
结论:修改p1的address对象后,浅克隆后的p2中的address对象也会被动地改变
深克隆的方式:
与浅克隆相比,深克隆需要在重写clone()方法时做一些手脚
@Override
protected Object clone() throws CloneNotSupportedException {
Person p = (Person) super.clone(); //获取一个浅复制对象
p.setAddress((Address) p.getAddress().clone());//将对象中需要深复制的属性再克隆一次(自定义的对象也需要实现Cloneable接口)
return p;
}
【注:Address类也要实现Cloneable接口,并且Address类中的属性必须全部是基本数据类型,否则还要继续嵌套下去】
运行结果:
结论:深克隆后,自定义对象也会复制一份。