引用拷贝、对象拷贝、浅拷贝、深拷贝
1、什么是引用拷贝
拷贝时只拷贝了一个对象的引用,使得拷贝引用和被拷贝引用指向同一个对象
Student a = new Student();
Student b = a;
2、什么是对象拷贝
拷贝时会将待拷贝的对象创建一个新的放在堆中,然后生成一个新的引用指向它。
前提是Student重写了了clone方法,注意不需要非得继承Cloneable
接口,只是一个声明接口
clone()
接口是Object
类中一个protected final
方法
Student a = new Student();
Student b = (Student)a.clone();
3、浅拷贝和深拷贝
首先要说明的是,浅拷贝和深拷贝都是属于对象拷贝的。
所不同的在于:
- 对于浅拷贝,待拷贝类中的基本数据类型是值传递,引用类型只是引用拷贝
- 对于深拷贝,待拷贝类中的基本数据类型是值传递,引用类型也是对象拷贝,该对象如果也有引用变量也需要递归下去
- 深拷贝需要自己在
clone()
方法中维护
如下是潜拷贝(上)和深拷贝(下)的对象图
Student
类中有引用变量Teacher
4、代码实现
4.1、引用拷贝
package copy;
/**
* 引用拷贝
*/
public class QuoteCopy {
public static void main(String[] args) {
QuoteTeacher quoteTeacher = new QuoteTeacher("riemann", 28);
QuoteTeacher otherQuoteTeacher = quoteTeacher;
// 输出一样
System.out.println(quoteTeacher);
System.out.println(otherQuoteTeacher);
}
}
class QuoteTeacher {
private String name;
private int age;
public QuoteTeacher(String name, int age) {
this.name = name;
this.age = age;
}
// get set...
}
4.2、对象拷贝
package copy;
/**
* 对象拷贝
* 深拷贝和浅拷贝都是对象拷贝
*/
public class ObjectCopy {
public static void main(String[] args) throws CloneNotSupportedException {
ObjectTeacher teacher = new ObjectTeacher("Richard Feynman", 25);
ObjectTeacher teacher2 = (ObjectTeacher) teacher.clone();
System.out.println(teacher);
System.out.println(teacher2);
}
}
class ObjectTeacher implements Cloneable {
private String name;
private int age;
public ObjectTeacher(String name, int age) {
this.name = name;
this.age = age;
}
// get set...
// 重写 Object类中的clone,方法体内调用Object类中的native方法
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
4.3、浅拷贝
package copy.shallow;
/**
* 潜拷贝
*/
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("riemann");
teacher.setAge(28);
Student student1 = new Student();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher);
Student student2 = (Student) student1.clone();
System.out.println("-------------拷贝后-------------");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("-------------修改老师的信息后-------------");
// 修改老师的信息
teacher.setName("jack");
System.out.println("student1的teacher为: " + student1.getTeacher().getName());
System.out.println("student2的teacher为: " + student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
private int age;
// get set (name, age)
}
class Student implements Cloneable {
private String name;
private int age;
// 深浅拷贝就是看类中的引用对象是否是对象拷贝
private Teacher teacher;
// get set (name, age)
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
// 和对象拷贝一样
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
4.4、深拷贝
package copy.deap;
public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("riemann");
teacher.setAge(28);
Student student1 = new Student();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher);
Student student2 = (Student) student1.clone();
System.out.println("-------------拷贝后-------------");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("-------------修改老师的信息后-------------");
// 修改老师的信息
teacher.setName("jack");
System.out.println("student1的teacher为: " + student1.getTeacher().getName());
System.out.println("student2的teacher为: " + student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
private int age;
// get set (name, age)
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student implements Cloneable {
private String name;
private int age;
private Teacher teacher;
// get set (name, age)
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
// 浅拷贝时:
// Object object = super.clone();
// return object;
// 改为深拷贝:
Student student = (Student) super.clone();
// 本来是浅拷贝,现在将Teacher对象复制一份并重新set进来
student.setTeacher((Teacher) student.getTeacher().clone());
return student;
}
}