1.使用序列化和反序列化的方式实现深拷贝

2.User类

package com.ydlclass.com.ydlclass.serializable;

import java.io.Serializable;

public class User implements Serializable,Cloneable {
    private static final long serialVersionUID = 1L;

    private int age;

    private  String sex;//不需要序列化字段

    private Dog dog;

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public User(int age, String sex) {
        this.age = age;
        this.sex = sex;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public User() {
    }

    public User(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", sex='" + sex + '\'' +
                ", dog=" + dog +
                '}';
    }
    //重写clone方法


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

3.Dog类

package com.ydlclass.com.ydlclass.serializable;

import java.io.Serializable;

public class Dog implements Serializable {
    private static final long serialVersionUID = 2540140443573702121L;
    private int age;

    public Dog(int age) {
        this.age = age;
    }

    public Dog() {
    }

    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                '}';
    }
}

4.类实现Clonable接口实现浅拷贝,使用序列化的方式实现深拷贝。

package com.ydlclass.com.ydlclass.serializable;

import org.junit.Test;

import java.io.*;

public class SerializableTest {
    @Test
    //浅拷贝
    public void testIndeepCopy() throws CloneNotSupportedException {
        User u1 = new User(12, "男");
        u1.setDog(new Dog(2));
        User user = (User) u1.clone();//克隆方法返回值是一个Object对象,需要强转成USer
        user.setAge(16);
        //如果不克隆,那么更改user,会影响u1
        user.getDog().setAge(123);//此时修改狗的岁数,发现狗被修改了;浅拷贝
        System.out.println(u1);

    }
    @Test
    //使用序列化的方式实现深拷贝
    public void testDeepCopy() throws CloneNotSupportedException, IOException, ClassNotFoundException {
        User u1 = new User(12, "男");
        u1.setDog(new Dog(2));

        //总的思路就是将需要深拷贝的对象实现序列化,引用的对象同样需要实现序列化;将对象输出至一个byte数组,再用流堵回来即可


        //将对象输出到字节数组当中
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//维护了一个byte数组
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(u1);

        //获取字节数组,此时虽然是一个数组,但是他是序列化的流,需要使用流反序列化成为一个对象;
        byte[] bytes = outputStream.toByteArray();

        //使用输入流读取出来,
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        Object o = objectInputStream.readObject();
        User copyUser = (User) o;
        System.out.println(u1);
        copyUser.getDog().setAge(12);//修改对象dog不会导致原本的对象发生改变,于是实现了深拷贝;
        System.out.println(copyUser);

    }


}

5.序列化的方式实现深拷贝代码比较多,可以使用泛型实现深拷贝的工具类;

泛型工具类序列化反序列化的方式实现深拷贝:

DeepCopyUtil:

package com.ydlclass.com.ydlclass.serializable;

import java.io.*;

public class DeepCopyUtil {
    public static <T> T deepCopy(T t) throws IOException, ClassNotFoundException {

        //总的思路就是将需要深拷贝的对象实现序列化,引用的对象同样需要实现序列化;将对象输出至一个byte数组,再用流堵回来即可


        //将对象输出到字节数组当中
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//维护了一个byte数组
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(t);

        //获取字节数组,此时虽然是一个数组,但是他是序列化的流,需要使用流反序列化成为一个对象;
        byte[] bytes = outputStream.toByteArray();

        //使用输入流读取出来,
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        Object o = objectInputStream.readObject();

        //关闭流
        objectInputStream.close();
        byteArrayInputStream.close();
        objectOutputStream.close();
        outputStream.close();


        return (T) o;
    }
}

使用工具类:

package com.ydlclass.com.ydlclass.serializable;

import org.junit.Test;

import java.io.*;

public class SerializableTest {

    @Test
    //使用序列化的方式实现深拷贝
    public void testDeepCopy() throws CloneNotSupportedException, IOException, ClassNotFoundException {
        User u1 = new User(12, "男");
        u1.setDog(new Dog(2));

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(u1);

        //使用工具类实现深拷贝
        User copyUser = DeepCopyUtil.deepCopy(u1);
        System.out.println(u1);
        copyUser.getDog().setAge(12);
        System.out.println(copyUser);

    }


}