浅拷贝:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原来对象的属性所指向的对象的内存地址。
深拷贝:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
换言之,深拷贝把要复制的对象所引用的对象都复制了一遍
package org.springblade.modules.prototype;
import lombok.Data;
import java.io.*;
/**
* @author zdx
* @description
*/
@Data
public class Person implements Cloneable, Serializable {
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
return person;
}
}
package org.springblade.modules.prototype;
import lombok.Data;
import java.io.Serializable;
/**
* @author zdx
* @description
*/
@Data
public class Address {
private String name;
}
package org.springblade.modules.prototype;
/**
* @author zdx
* @description
*/
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Address address = new Address();
address.setName("福建省");
person.setAddress(address);
Person person1 = (Person) person.clone();
System.out.println("person == person1=======" + (person == person1));
System.out.println("person.getAddress() == person1.getAddress()===========" + (person.getAddress() == person1.getAddress()));
}
}
我们可以看出 person和person1里面的address对象是同一个所以当前是浅拷贝。
接下来我们通过两种方式来实现深拷贝
1.传统的方式实现,在person实体类中重写clone方法(必须先实现Cloneable接口),Address实体类也要实现Cloneable接口
2.采用对象序列化和反序列化的方式(推荐方式)
(1)persion和address两个实体类都要实现序列化接口Serializable
(2)persion实体类重写clone方法
package org.springblade.modules.prototype;
import lombok.Data;
import java.io.*;
/**
* @author zdx
* @description
*/
@Data
public class Person implements Cloneable, Serializable {
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
return deepClone();
}
public Person deepClone() {
try {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream bis = new ObjectInputStream(bais);
return (Person) bis.readObject();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。