1、概念
使用原型实例,指定创建对象的种类,并且通过复制这些原型创建新的对象。
2、Cloneable接口
class Professor{
String name;
int age;
Professor(String name, int age) {
this.name = name;
this.age = age;
}
}
class Student implements Cloneable {
String name;
int age;
Professor p;// 引用
Student(String name, int age, Professor p) {
this.name = name;
this.age = age;
this.p = p;
}
@Override
public Object clone() {
Student o = null;
try {
o = (Student) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
public class CloneTest {
public static void main(String[] args) {
Professor p = new Professor("wangwu", 50);
Student s1 = new Student("zhangsan", 18, p);
System.out.println(s1.name + " " + s1.p.name + " " + s1.p.age);
Student s2 = (Student) s1.clone();
// s2的Professor信息
s2.p.name = "lisi";
s2.p.age = 30;
// s2的信息
s2.name = "z";
s2.age = 45;
System.out.println(s1.name + " " + s1.p.name + " " + s1.p.age);
}
}
输出:
zhangsan wangwu 50
zhangsan lisi 30
发现问题:
改变s1的拷贝对象s2的professor的信息,竟然也改变了s1的professor的信息
1)浅拷贝
对于基本数据类型,copy和原型是相等且独立的,copy的变化不会引起原型的变化;
对于引用数据类型,copy和原型是统一的,即二者指向同一个对象,即堆中的同一块区域。
所以,copy中引用的变化,会引起原型的变化。
2)深拷贝
针对浅拷贝中引用的问题,在clone()函数中,对引用对象手动进行拷贝,解决浅拷贝问题,即深拷贝。
浅拷贝只考虑当前拷贝的对象,不考虑该对象引用的对象;
深拷贝不仅考虑当前的对象,还考虑所有引用的对象。
class Professor implements Cloneable {
String name;
int age;
Professor(String name, int age) {
this.name = name;
this.age = age;
}
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
class Student implements Cloneable {
String name;
int age;
Professor p;
Student(String name, int age, Professor p) {
this.name = name;
this.age = age;
this.p = p;
}
public Object clone() {
Student o = null;
try {
o = (Student) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
o.p = (Professor) p.clone();
return o;
}
}
输出:
zhangsan wangwu 50
zhangsan wangwu 50