Java 深复制与浅复制

Java 深复制与浅复制

Java里Object类有个方法clone(),访问类型是protected。该方法用于对对象的克隆。注意克隆不包含静态资源。
      浅克隆(复制):浅复制只复制对象本身的8种基本数据类型及其他们的包装类型,不复制它所引用的对象本身。
      深克隆(复制):复制对象的所有类型数据,相当于将对象本身数据及其对象中引用到的对象,在堆内存中重新写了一份。

从内存角度对浅复制和深复制进行表示,如下图所示:
这里写图片描述

举个例子来看一下浅复制:

/**
 * Created by 杨Sir on 2017/11/17.
 * 学生类
 */
public class Student implements Cloneable{

    private Integer sId;
    private String stuName;
    private Teacher teacher;

    public Student() {
    }

    public Student(Integer sId, String stuName, Teacher teacher) {
        this.sId = sId;
        this.stuName = stuName;
        this.teacher = teacher;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Integer getsId() {
        return sId;
    }

    public void setsId(Integer sId) {
        this.sId = sId;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Teacher getTeacher() {
        return teacher;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "sId=" + sId +
                ", stuName='" + stuName + '\'' +
                ", teacher=" + teacher +
                '}';
    }
/**
 * Created by 杨Sir on 2017/11/17.
 * 教师类,供学生对象引用
 */
public class Teacher {

    private int Id;
    private String name;
    private Integer age;

    public Teacher() {

    }

    public Teacher(int id, String name, Integer age) {

        Id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "Id=" + Id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
/**
 * Created by 杨Sir on 2017/11/17.
 * 浅复制测试
 */
public class QianMain {

    public static void main(String[] args) throws CloneNotSupportedException {

        Teacher teacher = new Teacher(1001,"王老师",22);
        Student student = new Student(1060001,"小明",teacher);
        //打印原对象
        System.out.println("原对象student:" + student);

        //浅克隆student对象
        Student studentClone = (Student) student.clone();
        System.out.println("克隆对象studentClone:" + studentClone);
        System.out.println("-------------------------------- \n");

        //修改克隆对象的 基本类型数据和包装类型数据
        studentClone.setsId(1060002);
        studentClone.setStuName("杨小明");
        //打印原对象和克隆对象,,根据结果我发现 Integer和String类型被进行了深复制。证明 8种基本类型,包装类型和String类型默认进行深复制
        System.out.println("原对象student:" + student);
        System.out.println("克隆对象studentClone:" + studentClone);
        System.out.println("-------------------------------- \n");

        //修改克隆对象的 引用类型数据
        studentClone.getTeacher().setAge(21);
        studentClone.getTeacher().setName("王Sir");
        /**
         * 打印原对象和克隆对象
         * 原对象student:Student{sId=1060001, stuName='小明', teacher=Teacher{Id=1001, name='王Sir', age=21}}
         * 克隆对象studentClone:Student{sId=1060002, stuName='杨小明', teacher=Teacher{Id=1001, name='王Sir', age=21}}
         * 结果说明:对原对象中引用的对象进行了浅复制,相当于只复制了引用,两个引用指向同一个对象。
         */
        System.out.println("原对象student:" + student);
        System.out.println("克隆对象studentClone:" + studentClone);

    }
}

如果我们希望克隆的对象能够独立于原对象,即深复制,那么我们有两种方法:
      ①. 深克隆(复制):对深克隆的理解前面已经描述过,此处不再赘述。
      ②. 序列化:序列化是通过通过将对象序列化为流进行传输,可以先存到磁盘中,然后在以反序列化的方式序列化出对象。

为了不使篇幅过长,深复制的完整代码和序列化进行深复制的完整代码在我的github中存放,地址是:https://github.com/yangSirKo/JavaCloneObject ,在案例中我详细注释了每一步的作用及结果,并且将序列化对象和反序列化对象封装为了工具类,在工具类中使用了静态的泛型方法,防止类型丢失以及类型转换异常。大家可以下载下来自己写一写~~ 喜欢就留个赞啦(github中点击Star哦)。

猜你喜欢

转载自blog.csdn.net/annotation_yang/article/details/78564231