克隆
如People p=p1;
这不是克隆,而是两个对象指向一个堆。
@Test
public void test() {
Teacher teacher=new Teacher("男");
People p=new People(10,"张三",teacher);
People p1=p;//指向一个堆
System.out.println(p.getName());
p.setName("李四");//修改p对象的值,p1也随之改变。
System.out.println(p1.getName());
}
浅克隆
仅仅是对对象成员的克隆。
- 克隆对象的类实现Cloneable接口,重写里面的克隆方法,让其对象可以访问clone(),clone()不需做任何改动。
- 在需要的位置调用clone()克隆给另一个对象。
class Teacher{
private String sex;
public Teacher(){}
public Teacher(String sex) {
this.sex = sex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
class People implements Cloneable{
private Teacher teacher;
private int age;
private String name;
public People(){}
public People(int age, String name) {
this.age = age;
this.name = name;
}
public People(int age, String name,Teacher teacher) {
this.teacher = teacher;
this.age = age;
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return age+"--"+name;
}
}
@Test
public void test2() {
Teacher teacher=new Teacher("男");
People p=new People(10,"张三",teacher);
try {
People p2=(People)p.clone();
System.out.println(p.getAge());
System.out.println(p2.getAge());
p.setAge(11);
System.out.println(p.getAge());//只p自己变为11
System.out.println(p2.getAge());//p2不变克隆成功
System.out.println(p.getTeacher().getSex());
System.out.println(p2.getTeacher().getSex());
p.getTeacher().setSex("女");
System.out.println(p.getTeacher().getSex()); System.out.println(p2.getTeacher().getSex());
//p p2都发生改变,克隆失败,由此可见浅克隆只能克隆本身,而不能克隆通过其他字段关联的其他对象
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
深克隆
不仅克隆自身对象成员,而其还克隆通过其他字段关联的其他对象。
1. 在浅克隆的基础上,关联的其他对象的类也要实现Cloneable接口,并重写clone(),clone不需进行改动。
2. 为关联的对象封装好getter/setter,并添加带对象的构造器。
3. 此时要重写clone() 将A1 指向B的箭头指向B1。
class People implements Cloneable{
private Teacher teacher;
private int age;
private String name;
public People(){}
public People(int age, String name) {
this.age = age;
this.name = name;
}
public People(int age, String name,Teacher teacher) {
this.teacher = teacher;
this.age = age;
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// return super.clone();
People p=(People)super.clone();
p.teacher=(Teacher) this.teacher.clone();
return p;
}
@Override
public String toString() {
return age+"--"+name;
}
}
class Teacher implements Cloneable{
private String sex;
public Teacher(){}
public Teacher(String sex) {
this.sex = sex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Test
public void test3() {
Teacher teacher=new Teacher("男");
People p=new People(10,"张三",teacher);
try {
People p2=(People)p.clone();
System.out.println(p.getAge());
System.out.println(p2.getAge());
p.setAge(11);
System.out.println(p.getAge());//只p自己变为11
System.out.println(p2.getAge());//p2不变克隆成功 System.out.println(p.getTeacher().getSex()); System.out.println(p2.getTeacher().getSex());
p.getTeacher().setSex("女"); System.out.println(p.getTeacher().getSex());//只p自己变为,克隆成功 System.out.println(p2.getTeacher().getSex());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}