Java中有 基本数据类型(元类型),和 类的实例对象 这个引用数据类型。而一般使用 『 = 』号做赋值操作的时候。对于基本数据类型,实际上是拷贝的它的值,但是对于对象而言,其实赋值的只是这个对象的引用,将原对象的引用传递过去,他们实际上还是指向的同一个对象。
浅拷贝:
只对类中基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。
package copy;
/**
* @Author Snail
* @Describe 浅拷贝
* @CreateTime 2019/6/23
*/
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student();
student1.setAge(29);
student1.setTeacher(new Teacher());
//利用clone()方法创建一个新的对象,实现了一次浅拷贝
Student student2= (Student) student1.clone();
System.out.println("student1::"+student1);
System.out.println("student2::"+student2);
//其对象(teacher)的地址空间是一样的,是浅拷贝的特征
System.out.println("student1.getTeacher()::"+student1.getTeacher());
System.out.println("student2.getTeacher()::"+student2.getTeacher());
// student1::copy.Student@66a29884
// student2::copy.Student@4769b07b
// student1.getTeacher()::copy.Teacher@cc34f4d
// student2.getTeacher()::copy.Teacher@cc34f4d
}
}
class Teacher {
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;
}
}
class Student implements Cloneable{
private int age;
private Teacher teacher;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
深拷贝:
在对类中引用数据类型(类的实例对象)进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝
package copy;
/**
* @Author Snail
* @Describe 深拷贝
* @CreateTime 2019/6/23
*/
public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student();
student1.setAge(29);
student1.setTeacher(new Teacher());
Student student2= (Student) student1.clone();
System.out.println("student1::"+student1);
System.out.println("student2::"+student2);
//深拷贝,其引用数据类型地址空间不一致
System.out.println("student1.getTeacher()::"+student1.getTeacher());
System.out.println("student2.getTeacher()::"+student2.getTeacher());
// student1::copy.Student@66a29884
// student2::copy.Student@4769b07b
// student1.getTeacher()::copy.Teacher@cc34f4d
// student2.getTeacher()::copy.Teacher@17a7cec2
}
}
class Teacher 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;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student implements Cloneable{
private int age;
private Teacher teacher;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
//深拷贝
Student student=(Student) super.clone();
//拷贝引用数据类型
student.teacher= (Teacher) this.teacher.clone();
return student;
}
}
总结:
浅拷贝和深拷贝是相对的,如果一个对象内部只有基本数据类型,那用 clone() 方法获取到的就是这个对象的深拷贝,而如果其内部还有引用数据类型,那用 clone() 方法就是一次浅拷贝的操作。