版权声明:本文为博主原创文章,未经博主允许不得转载!!! https://blog.csdn.net/qq_19107011/article/details/79491982
深克隆就是:进行克隆以后,引用对象的地址改变了。
浅克隆就是:进行克隆以后,引用对象的地址没有改变。
二种克隆都会重新复制基本数据类型(int,long等非final属性,包括string)
举个栗子:
package com.nameshame;
import java.util.ArrayList;
public class TestClone {
public static void main(String[] args) {
ArrayList<TestClone> a = new ArrayList<TestClone>();
a.add(new TestClone());
TestClone obj1 = a.get(0);
ArrayList a2 = (ArrayList) a.clone();
TestClone obj2 = a.get(0);
System.out.println("克隆前后是否是同一个对象:"+(obj1==obj2));
}
}
ayList的clone这个方法是属于哪一种克隆方法。
输出为:
克隆前后是否是同一个对象:true
所以,它属于浅克隆,图解如下:
下面看看我们把程序改成,对ArrayList进行深克隆。
package com.nameshame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
public class TestClone implements Serializable{
public static void main(String[] args) throws Exception{
ArrayList<TestClone> a = new ArrayList<TestClone>();
a.add(new TestClone());
TestClone obj1 = a.get(0);
//使用序列化,进行深克隆
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(a);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
a = (ArrayList) ois.readObject();
TestClone obj2 = a.get(0);
System.out.println("克隆前后是否是同一个对象:"+(obj1==obj2));
}
}
程序的输出为
克隆前后是否是同一个对象:false
所以我们使用序列化和反序列化,进行通过二进制进行对象的深克隆。
图解如下:
所以,从上面二个图就可以看出一个重要的地方。就是深克隆比浅克隆多了对对象里面引用对象的克隆操作。
之外,说下深克隆的通用实现。
如果类A需要进行深克隆。那么可以重新clone方法,然后在方法new一个新的对象返回。
这个就是通用的实现了。
同时A类需要实现Cloneable接口,这是一个标记接口。
主要就这2点。
告辞!