浅克隆
public static void main(String[] args) {
User user01=new User();
user01.setId(1);
User user02=user01.clone();
System.out.println(JSONObject.toJSONString(user02));
user01.setId(2);
System.out.println(JSONObject.toJSONString(user02));
}
private static class User implements Cloneable{
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
protected User clone(){
User user=null;
try {
user=(User)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return user;
}
}
需要实现Cloneable接口,标识User类中的clone方法是合法的,否则将会抛出CloneNotSupportedException异常,如果出现示例中存在复杂类型,比如如下pojo
private static class User implements Cloneable{
private Integer id;
private Address address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected User clone(){
User user=null;
try {
user=(User)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return user;
}
}
private static class Address implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Address clone(){
Address address=null;
try {
address=(Address)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return address;
}
}
执行如下代码:
User user01=new User();
user01.setId(1);
Address address01=new Address();
address01.setName("深圳");
user01.setAddress(address01);
User user02=user01.clone();
System.out.println(JSONObject.toJSONString(user02));
user01.setId(2);
user01.getAddress().setName("广州");
System.out.println(JSONObject.toJSONString(user02));
会发现修改第一个实例,克隆后的第二个实例也会同步修改,这样浅克隆就不能满足条件了,就有了深克隆
修改User中的clone方法,
@Override
protected User clone(){
User user=null;
try {
user=(User)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//实例变量分配内存空间
user.address=this.address.clone();
return user;
}
clone的User实例时同时cone Addres示例。
这样clone出了就是两个实例。
如果嵌套很多层,一个个就比较麻烦,就有了序列化克隆方式
private static class User implements Serializable{
private Integer id;
private Address address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
protected User clone(){
User user=null;
try {
// 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
// 将流序列化成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
user = (User) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return user;
}
}
private static class Address implements Serializable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
参考:https://mp.weixin.qq.com/s/iVm7vT7nGxHDR-ipJIMR6g