Java基础——拷贝

xiaoxiao2025-11-11  7

引用拷贝,只是单纯的将一个对象赋值给另一个对象,两个对象的引用地址完全一样。

举例:

Teacher teacher = new Teacher("Tom",26);

Teacher otherteacher = teacher;

System.out.println(teacher);

System.out.println(otherteacher);

输出结果:

blog.Teacher@355da254

blog.Teacher@355da254

结果分析:

由输出结果可以看出,他们的地址值是相等的,那么它们其实是同一个对象。两个对象都指向同一个对象。都是new Teacher("Tom",26)。这就是引用拷贝。

 

对象拷贝,是指将对象完全复制,两个对象互不影响,引用地址也不同。并且分为浅拷贝深拷贝。

举例:

Teacher teacher = new Teacher("Swift",26); Teacher otherteacher = (Teacher)teacher.clone(); System.out.println(teacher); System.out.println(otherteacher); 输出结果:

blog.Teacher@355da254

blog.Teacher@4dc63996

结果分析:

由输出结果可以看出,他们的地址是不同的,也就是两个对象都有自己的引用变量。

接下来就是 浅拷贝和深拷贝的区别

被复制对象的所有变量都含有与原来的对象相同的值,

而所有的对其他对象的引用仍然指向原来的对象。

即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

简而言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象 

浅拷贝示例:

package blog;

/**  * Created by 白夜行 on 2017/5/8.  */ public class ShallowCopy {     public static void main(String[] args) throws CloneNotSupportedException {         Teacher teacher = new Teacher();         teacher.setName("Delacey");         teacher.setAge(29);

        Student2 student1 = new Student2();         student1.setName("Dream");         student1.setAge(18);         student1.setTeacher(teacher);

        Student2 student2 = (Student2) 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("Jam");         System.out.println(student1.getTeacher().getName());         System.out.println(student2.getTeacher().getName());     }

}

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;     }

}

class Student2 implements Cloneable {     private String name;     private int age;     private Teacher teacher;

    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 Teacher getTeacher()     {         return teacher;     }

    public void setTeacher(Teacher teacher)     {         this.teacher = teacher;     }

    @Override     public Object clone() throws CloneNotSupportedException     {         Object object = super.clone();         return object;     }

}

输出结果:

拷贝后

Dream 18

Delacey 29

修改老师的信息后-------------

Jam

Jam

结果分析:

虽然两个student对象是不一样的,但是student引用的teacher是同一个对象,这就是 浅拷贝

深拷贝:

深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

 

简而言之,深拷贝把要复制的对象所引用的对象都复制了一遍,深拷贝都需要对象实现接口(Cloneable或是Serializable)

深拷贝示例一:

package blog;

/**  * Created by 白夜行 on 2017/5/8.  */

public class DeepCopy {     public static void main(String[] args) throws Exception     {         Teacher2 teacher = new Teacher2();         teacher.setName("Delacey");         teacher.setAge(29);

        Student3 student1 = new Student3();         student1.setName("Dream");         student1.setAge(18);         student1.setTeacher(teacher);

        Student3 student2 = (Student3) 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("Jam");         System.out.println(student1.getTeacher().getName());         System.out.println(student2.getTeacher().getName());     } }

class Teacher2 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     public Object clone() throws CloneNotSupportedException     {         return super.clone();     }

}

class Student3 implements Cloneable {     private String name;     private int age;     private Teacher2 teacher;

    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 Teacher2 getTeacher()     {         return teacher;     }

    public void setTeacher(Teacher2 teacher)     {         this.teacher = teacher;     }

    @Override     public Object clone() throws CloneNotSupportedException     {         // 浅复制时:         // Object object = super.clone();         // return object;

        // 改为深复制:         Student3 student = (Student3) super.clone();         // 本来是浅复制,现在将Teacher对象复制一份并重新set进来         student.setTeacher((Teacher2) student.getTeacher().clone());         return student;     }

}输出结果:

拷贝后

Dream 18

Delacey 29

修改老师的信息后-------------

Jam

Delacey

结果分析:

这次不论student还是引用的teacher都是单独的对象,完全不相同。这就是深拷贝

深拷贝示例二:

package blog;

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable;

/**  * Created by 白夜行 on 2017/5/13.  */ public class DeepCopyServiable {     public static void main(String[] args) throws Exception {         Teacher3 t = new Teacher3();         t.setName("Taylor");         t.setAge(28);

        Student3 s1 = new Student3();         s1.setAge(20);         s1.setName("blank space");         s1.setTeacher(t);

        Student3 s2 = (Student3) s1.deepClone();

        System.out.println("拷贝后:");         System.out.println(s2.getName());         System.out.println(s2.getAge());         System.out.println(s2.getTeacher().getName());         System.out.println(s2.getTeacher().getAge());         System.out.println("---------------------------");

        t.setName("swift");

        System.out.println("修改后:");         System.out.println(s1.getTeacher().getName());         System.out.println(s2.getTeacher().getName());     }

}

class Teacher3 implements Serializable {     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 Student3 implements Serializable {     private String name;     private int age;     private Teacher3 teacher;

    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 Teacher3 getTeacher()     {         return teacher;     }

    public void setTeacher(Teacher3 teacher)     {         this.teacher = teacher;     }

    public Object deepClone() throws Exception     {         // 序列化         ByteArrayOutputStream bos = new ByteArrayOutputStream();         ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(this);

        // 反序列化         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());         ObjectInputStream ois = new ObjectInputStream(bis);

        return ois.readObject();     }

}输出结果:

拷贝后:

blank space 20

Taylor 28

---------------------------

修改后:

swift

Taylor

结果分析:

说明序列化的方式实现了对象的拷贝。

可以这么理解,我只是为了自己看起来方便些,重新排版了下。

我发现深拷贝浅拷贝 其实都是需要实现拷贝接口或是序列化接口,并在类中创建一个这样的拷贝方法。感觉对类进行了进一步的拓展。不过对于拷贝这种方法的使用,目前好像没有发现太多的使用场景。如果说得不对,请大家指出,谢谢~

以及的代码及文字都是转至下面这位的博客,感谢~ 作者:白夜行515  来源:  原文:https://blog.csdn.net/baiye_xing/article/details/71788741  版权声明:本文为博主原创文章,转载请附上博文链接!

转载请注明原文地址: https://www.6miu.com/read-5039440.html

最新回复(0)