Java之深拷贝与浅拷贝的理解
前言
拷贝一词大家都不陌生,在我们日常使用计算机的时候,Ctrl+C就是一种拷贝,但是在java中拷贝有不同的方式,在拷贝的类型上也会有不一样的地方。
提示:以下是本篇文章正文内容,下面案例可供参考
1、引用拷贝
拷贝一个对象的引用,例如
public class Clone {
public static void main(String[] args) {
Student s = new Student("张三");
Student s1 = s;
System.out.println(s+"+"+s1);
}
private static class Student implements Cloneable{
private String name;
Student(String name){
this.name=name;
}
private void setName(String name) {
this.name = name;
}
}
}
打印出来结果为
所以也就表示,s与s1指向的是同一个对象,都是Student
这就是引用拷贝。
2、对象拷贝
对象拷贝也就是创建一个对象的副本。
public static void main(String[] args) throws CloneNotSupportedException{
Student s = new Student("张三");
Student s1 = (Student) s.clone();
System.out.println(s+"+"+s1);
}
public class Student implements Cloneable{
private String name;
Student(String name){
this.name=name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
}
调用Object中的clone方法之后可以看到
现在s与s1 的地址是不同的,所以是创建了一个新的对象。
浅拷贝与深拷贝
浅拷贝与深拷贝都为对象拷贝
浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。
public class Clone{
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("张三");
Student student1 = new Student();
student1.setName("李四");
student1.setTeacher(teacher);
Student student2 = (Student) student1.clone();
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
teacher.setName("jack");
System.out.println( student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student implements Cloneable {
private String name;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
}
最后结果为
也就是说明,这两个学生对象中的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;
}
这里和浅拷贝唯一的不同在于,在浅拷贝时时直接把对象的引用拷贝了进去,但是深拷贝的改变就是,在浅拷贝时,把被拷贝的对象中的对象依旧拷贝了一份放入了要拷贝对象中。