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