Cloneable接口:实现此接口,以指示Object.clone()可以合法的对该类实例进行按字段复制。如果没有实现Object的clone方法,则会导致抛出CloneNotSupportedException异常。复制分2种:
- 浅表复制:被克隆对象内部成员变量只含基本数据类型时,只需进行浅表复制
- 深表复制:被克隆对象内部成员变量含有非基本数据类型时,需要进行深表复制
浅表复制:
class Student implements Cloneable {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 浅表复制,被克隆对象内所有成员变量都为基本类型时
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e.getMessage());
}
}
}
深表复制:
class Teacher implements Cloneable {
public String name;
public Student student1;
public Student student2;
public Teacher(String name, Student student1, Student student2) {
this.name = name;
this.student1 = student1;
this.student2 = student2;
}
// 深表复制,被克隆对象内含有非基本类型成员变量时
public Object clone() {
try {
Teacher t = (Teacher) super.clone();
t.student1 = (Student) student1.clone(); //深表复制
//t.student2 = (Student) student2.clone();
//this.student2将不会被复制,t.student2只保存this.student2实例的引用
return t;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
throw new Error(e.getMessage());
}
}
}
测试:
public class CloneableTest {
public static void main(String[] args) {
Student s1 = new Student("s1", 13);
Student s2 = new Student("s2", 14);
Teacher t = new Teacher("t", s1, s2);
Teacher t2 = (Teacher) t.clone();
Student s3 = (Student) s1.clone();
System.out.println(s3.name); //输出:s1
s1.name = "ss1";
System.out.println(s3.name); //输出:s1,
//浅表复制成功,说明基本类型成员变量只需浅表复制即可
System.out.println(t2.student1.name); //输出:s1
System.out.println(t2.student2.name); //输出:s2
t.student1.name = "s11";
t.student2.name = "s22";
System.out.println(t2.student1.name); //输出:s1
System.out.println(t2.student2.name); //输出:ss2
//在Teacher类的clone方法中,student2没有进行深表复制,克隆出来的t1.student2
//只保存了t.student2实例的引用,当t.student2改变时t1.student2将跟着改变
}
}