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;@Overrideprotected 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overrideprotected 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();//cloneSystem.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的值没有改变,这就是深拷贝。
如下图:
深拷贝:
浅拷贝: