Java 中内置了一些很有用的接口, Clonable 就是其中之一。
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝"。 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。
浅拷贝:
class Money {
public double m = 99.99;
}
class Person implements Cloneable{
public Money money = new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class TestDemo3 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person();
Person person2 = (Person) person.clone();
System.out.println("通过person2修改前的结果");
System.out.println(person1.money.m);System.out.println(person2.money.m);
person2.money.m = 13.6;
System.out.println("通过person2修改后的结果");
System.out.println(person1.money.m);
System.out.println(person2.money.m);
}
}
// 执行结果
通过person2修改前的结果
99.99
99.99
通过person2修改后的结果
13.6
13.6
如上代码,我们可以看到,通过clone,我们只是拷贝了Person对象。但是Person对象中的Money对象,并没有拷贝。通过person2这个引用修改了m的值后,person1这个引用访问m的时候,值也发生了改变。这里就是发生了浅拷贝。
深拷贝:
class Money implements Cloneable{ public double m = 19.9; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable { public String name; public int age; public Money money = new Money(); public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { //这里面在克隆person 但是我没看到你克隆money,那么怎么克隆呢? Person tmp = (Person) super.clone(); tmp.money = (Money) this.money.clone(); return tmp; //return super.clone(); } } public class Test { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person("张三", 10); Person person2 = (Person) person.clone();//clone System.out.println("person " + person.money.m); System.out.println("person2 " + person2.money.m); System.out.println("==========="); person.money.m = 99.99; System.out.println("person " + person.money.m); System.out.println("person2 " + person2.money.m); } }结果:
person 19.9
person2 19.9
===========
person 99.99
person2 19.9
如上代码,person不仅拷贝了person对象,而且拷贝了person里面的money,然后改变了person里面的m的值,而person2的m的值没有改变,这就是深拷贝。
如下图:
深拷贝:
浅拷贝: