java中的浅拷贝与深拷贝
浅拷贝
实现方法:要拷贝的类,实现Cloneable接口,然后重写clone方法,即可实现浅拷贝。
但缺点在于,如果该类的成员包含其他类,则其他类并没有被拷贝,只是拷贝了一个引用对象,其指向的地址和之前的对象一致,因此,修改people1的宠物信息,people的宠物信息也变了。
package cn.flycold.深浅拷贝.浅拷贝;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liyutong03
* @description
* @date 2019/10/30
* Copyright (C) 2015 Meituan
* All rights reserved
*/
public class 浅拷贝 {
public static void main(String []args) throws CloneNotSupportedException{
Pet pet = Pet.builder().pAge(2).pName("包子").build();
People people = People.builder().age(23).name("lyt").pet(pet).build();
People people1 = people.clone();
System.out.println("people :" + people);
System.out.println("people1:" + people1);
people1.setName("zzz");
people1.setAge(19);
people1.getPet().setPName("馒头");
people1.getPet().setPAge(3);
System.out.println("after change people1");
System.out.println("people :" + people);
System.out.println("people1:" + people1);
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class People implements Cloneable{
private int age;
private String name;
private Pet pet;
@Override
public People clone() throws CloneNotSupportedException{
return (People) super.clone();
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Pet{
private String pName;
private int pAge;
}
深拷贝
我们可以用两种方法实现深拷贝
实现Cloneable接口
对要拷贝的类,以及其引用的类,都实现Cloneable接口,并重写clone方法。
注意,包含其他类的类,需要注意clone方法的实现,需要手动调用包含的类的clone方法
这种方法的劣势在于,层级太多的话代码会很麻烦。
实现Serializable接口
Serializable接口是用来序列化和反序列化的,我们用输出流将员对象序列化为字节,在用输入流将字节反序列化为对象,就实现了深拷贝,好处是简单,我们只需在类上标注其实现 Seriablizeable接口,注意,包含的类也要标注,即可。
package cn.flycold.深浅拷贝.深拷贝;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.*;
/**
* @author liyutong03
* @description
* @date 2019/10/30
* Copyright (C) 2015 Meituan
* All rights reserved
*/
public class 深拷贝 {
public static void main(String []args) throws Exception{
Pet pet = Pet.builder().pAge(2).pName("包子").build();
People people = People.builder().age(23).name("lyt").pet(pet).build();
// Cloneable实现深拷贝
// People people1 = people.clone();
// Serializable实现深拷贝
People people1 = (People) deepCopy(people);
System.out.println("people :" + people);
System.out.println("people1:" + people1);
people1.setName("zzz");
people1.setAge(19);
people1.getPet().setPName("馒头");
people1.getPet().setPAge(3);
System.out.println("after change people1");
System.out.println("people :" + people);
System.out.println("people1:" + people1);
}
public static Object deepCopy(Object object) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);
oos.writeObject(object);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
return ois.readObject();
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class People implements Cloneable, Serializable {
private int age;
private String name;
private Pet pet;
@Override
public People clone() throws CloneNotSupportedException{
People people = (People) super.clone();
people.setPet(people.getPet().clone());
return people;
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Pet implements Cloneable, Serializable{
private String pName;
private int pAge;
@Override
public Pet clone() throws CloneNotSupportedException{
return (Pet)super.clone();
}
}