clone方法
clone是定義一個(gè)Object類下基本方法之一:
protected native Object clone() throws CloneNotSupportedException;
使用的時(shí)候需要繼承object對(duì)象,并且為了可以使其它類調(diào)用該方法,覆寫克隆方法時(shí)必須將其作用域設(shè)置為public.
淺拷貝
淺拷貝就拷貝了對(duì)象本身,屬性值不變,也就是說(shuō)對(duì)象里面的引用還是原來(lái)對(duì)象里面的引用
class A implements Cloneable {
int a = 0;
int[] b = {1, 2};
@Override
protected Object clone() throws CloneNotSupportedException {
A a = null;
try {
a = (A) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return a;
}
}
測(cè)試一下
A a = new A();
A b = (A) a.clone();
System.out.println(b.a);
for (int i :b.b) {
System.out.print(i);
}
b.a = 1;
b.b[0] = 3;
b.b[1] = 4;
System.out.println(a.a);
for (int i :a.b) {
System.out.print(i);
}
測(cè)試結(jié)果是:
0 1,2
0 3,4
因?yàn)閍是基本類型所以值不變,但是b是引用類型,所以值也被改變了
深拷貝
和淺拷貝就一些細(xì)微區(qū)別,深拷貝是把對(duì)象中的屬性也進(jìn)行了一個(gè)拷貝
class A implements Cloneable {
int a = 0;
int[] b = {1, 2};
@Override
protected Object clone() throws CloneNotSupportedException {
A a = null;
try {
a = (A) super.clone();
// 對(duì)屬性進(jìn)克隆
a.b = b.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return a;
}
}
測(cè)試結(jié)果是:
0 1,2
0 1,2
循環(huán)引用
如果類中的對(duì)象引用了其他的對(duì)象,那么一次次去clone顯然不現(xiàn)實(shí)
借助java的序列化,A需要實(shí)現(xiàn)序列化接口,而且A中使用的所有對(duì)象都要實(shí)現(xiàn)序列化接口,否則會(huì)拋出NotSerializableException異常
@Override
protected Object clone() throws CloneNotSupportedException {
A a = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
a = (A) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return a;
}