为什么使用clone
存在一个对象A,A已有初始值,这时候可能需要一个新的对象B和A相同,但是A和B是两个独立的对象,任意一个改动都不影响其中一个的值,但是B的初始值由A确定,这时候clone就是最有效也是最简单的方法。
new一个对象和clone一个对象的区别
- new操作符的本意是分配内存空间,java程序执行到new操作符时,首先去看new操作符后面的类型,知道类型才能知道需要分配多大的内存空间,分配完成,调用构造函数,填充对象,完成对象的初始化。
- clone的第一步也是分配内存,java程序执行到clone这一步时,分配的内存和调用clone方法的对象相同,在根据原对象完成对新对象的初始化,一个新的对象就被创建完成。
复制对象和克隆对象
需要克隆的对象要继承Cloneable接口,并重写clone()方法
复制对象
定义类:
public class People1 {
private String name;
private Integer age;
public People1(String name, Integer age) {
this.name = name;
this.age = age;
}
}
复制测试
public class test {
public static void main(String[] args) {
People1 people1 = new People1("people",18);
People1 people11 = people1;
System.out.println(people1);
System.out.println(people11);
System.out.println(people1 == people11);
}
}
结果:
证明复制对象只是指向原来的对象,people1和people11只是引用同一个对象
clone对象
定义类:
public class People2 implements Cloneable{
private String name;
private Integer age;
public People2(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试:
public class test {
public static void main(String[] args) {
//clone
People2 people2 = new People2("people",18);
People2 people22 = null;
try {
people22 = (People2) people2.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(people2);
System.out.println(people22);
System.out.println(people2 == people22);
}
}
结果:
可以看出people2和people22指向的对象并不是同一个的
浅克隆与深克隆
定义类:
Student类:
public class Student implements Cloneable{
private String name;
private Integer age;
private Teacher teacher;
public Student(String name, Integer age,Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "学生: name=" + name + ", age=" + age + ",指导" + teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Teacher类
public class Teacher {
private String name;
private Integer age;
public Teacher(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "老师:name=" + name + ", age=" + age ;
}
}
浅克隆
main函数
public class test2 {
public static void main(String[] args) {
Teacher teacher = new Teacher("刘老师",18);
Student student1 = new Student("小明",10,teacher);
Student student2 = null;
try {
student2 = (Student) student1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
Teacher t1 = student2.getTeacher();
t1.setName("张老师");
t1.setAge(30);
student2.setName("小红");
student2.setAge(9);
student2.setTeacher(t1);
System.out.println(student1);
System.out.println(student2);
}
}
结果:
修改student2中的Teacher类,student1也跟着改变,而修改姓名和年龄并不会修改,由此得出才重新clone方法时不能直接super
深克隆
- Teacher继承Cloneable
- Student重写clone方法
Student newStudent = (Student) super.clone();
newStudent.teacher = (Teacher) teacher.clone();
return newStudent;
运行上方测试代码,结果:
完成预想结果
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。