应用场景
有一个Person类,main函数中有一个person1对象,现要将person1对象克隆一份给person2
代码如下:
public class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
Person person1 = new Person("zhangsan",18);
//Person person2 =
}
}
要用到 Object 类中的 clone() 方法
发现报错了,我们查看Object 类的源码,发现 Object 类中的 clone() 方法是 protected 修饰的,无法在不同包的不同类中使用,所以,我们需在Person类中重写clone()方法
重写clone()方法后,依旧报错,这时需要解决的问题,以下列举:
解决完上面两个问题后,编译已经不报错了 ,当我们运行后:
报错为:不支持克隆异常,这时我们需要实现 Cloneable 接口
当我们查看源码,发现它是一个空接口,也叫做标记接口,表示当前类是可以被克隆的
这时代码便执行无误了
堆栈图:
浅拷贝
如下代码:
Person类中新加一个Money类对象,并进行实例化
Money对象没有被克隆,person1和person2均指向同一个money
此时,若执行以下代码:
public class Test {
public static void main(String[] args)
throws CloneNotSupportedException{
Person person1 = new Person("zhangsan",18);
Person person2 = (Person) person1.clone();
System.out.println("修改前:" + person1.m.money);
System.out.println("修改前:" + person2.m.money);
person2.m.money = 99.99;
System.out.println("修改后:" + person1.m.money);
System.out.println("修改后:" + person2.m.money);
}
}
运行结果:
结论:只克隆了Person对象,没有克隆Money对象,这种现象就叫做——浅拷贝
深拷贝
如果即克隆了Person对象,又克隆了Money对象,就叫做——深拷贝
此时再执行以下代码:
public class Test {
public static void main(String[] args)
throws CloneNotSupportedException{
Person person1 = new Person("zhangsan",18);
Person person2 = (Person) person1.clone();
System.out.println("修改前:" + person1.m.money);
System.out.println("修改前:" + person2.m.money);
person2.m.money = 99.99;
System.out.println("修改后:" + person1.m.money);
System.out.println("修改后:" + person2.m.money);
}
}
运行结果:
结论:克隆方法没有深浅拷贝之分,深浅拷贝都是依靠具体代码去实现的
本章演示代码:
class Money implements Cloneable{
public double money = 9.9;
@Override
protected Object clone()
throws CloneNotSupportedException {
return super.clone();
}
}
public class Person implements Cloneable {
public String name;
public int age;
public Money m = 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 tmp = (Person) super.clone();
tmp.m = (Money) this.m.clone();
return tmp;
}
}
public class Test {
public static void main(String[] args)
throws CloneNotSupportedException{
Person person1 = new Person("zhangsan",18);
Person person2 = (Person) person1.clone();
System.out.println("修改前:" + person1.m.money);
System.out.println("修改前:" + person2.m.money);
person2.m.money = 99.99;
System.out.println("修改后:" + person1.m.money);
System.out.println("修改后:" + person2.m.money);
}
}