浅拷贝(浅克隆)和深拷贝(深克隆)
相关概念
- 什么是原型模式?
原型(Prototype)模式是一种对象创建型模式,他采取复制原型对象的方法来创建对象的实例。使用原型模式创建的实例,具有与原型一样的数据。
原型模式的特点:
1、由原型对象自身创建目标对象
2、目标对象是原型对象的一个克隆
3、根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
2.什么是浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对象。
3.什么是深拷贝?
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。
Cloneable接口
以下是JavaAPI中的解释:
这里是此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。
如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。
浅拷贝(浅克隆)
public class Student implements Cloneable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
测试类
public class Test {
public static void main(String[] args) {
Student stu=new Student ("张三",23);
System.out.println(stu.getName());
Student clone=(Student) stu.clone();
System.out.println(stu.getName());
System.out.println(clone.getName());
}
}
运行结果:
张三
张三
张三
深拷贝(深克隆)
1.Student类
public class Student implements Cloneable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
2.Teacher类
public class Teacher implements Cloneable{
private String name;
private int age;
private Student student;
public Teacher(String name, int age, Student student){
this.name = name;
this.age = age;
this.student = student;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public Object clone() {
Teacher teacher = null;
try {
teacher = (Teacher) super.clone();
teacher.student = (Student)student.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return teacher;
}
}
3.测试类
public class Test {
public static void main(String[] args) {
Student stu = new Student("张三", 18);
Teacher tea = new Teacher("李四", 33, stu);
System.out.println("克隆前的学生姓名:" + tea.getStudent().getName());
Teacher clone = (Teacher) tea.clone();
System.out.println("克隆后的学生姓名:" + clone.getStudent().getName());
}
}
4.运行结果
克隆前的学生姓名:张三
克隆后的学生姓名:张三
注:另外一种实现深克隆的方法是实现序列化
序列化:把对象写到流里
反序列化:把对象从流中读出来