- clone的過程
new 一個對象的過程和 clone 一個對象的過程區別
new 操作符的本意是分配內存。程序執行到 new 操作符時, 首先去看 new 操作符后面的類型,因為知道了類型, 才能知道要分配多大的內存空間。分配完內存之后,再調用構造函數,填充對象的各個域,這一步叫做對象的初始化, 構造方法返回后,一個對象創建完畢,可以把他的引用(地址)發布到外部,在外部就可以使用這個引用操縱這個對 象。
clone 在第一步是和 new 相似的, 都是分配內存,調用 clone 方法時,分配的內存和原對象(即調用 clone 方 法的對象)相同,然后再使用原對象中對應的各個域,填充新對象的域, 填充完成之后,clone 方法返回,一個新的 相同的對象被創建,同樣可以把這個新對象的引用發布到外部。
即相同點是:都會重新分配內存;不同點是clone的數據和原數據相同,而new的話數據是初始數據
- 引用復制
是一個對象,地址相同
A a=new A();
A b=a;
- 對象復制
不同對象,地址不同
前提:class A 需實現cloneable
且實現clone(){return super.clone()}
A a=new A();
A b=a.clone();
其中對于對象復制,分為淺復制和深復制
舉個例子
class A implement Cloneable{
int a;
String str;
C obj;
clone(){
return super.clone()
}
}
其中 默認的clone行為:super.clone() 對于基本數據對象是對象復制,而對于string及對象都是引用復制;
因此:
如果調用:
A a=new A();
B b=a.clone();
因為a實現了克隆接口,故a,b 是對象復制,是不同的對象;
但由于a只是實現了默認的克隆實現,因此
a.str==b.str
a.obj==b.obj
即a只是淺拷貝;
那a怎么實現深度拷貝呢? 那就需要改變默認的拷貝行為
class A{
...
clone(){
A copyA=(A)super.clone();
copyA.str=new String(str);
copyA.obj=(C)obj.clone();
return copyA;
}
}
這樣的話,即在class A這個層級實現了深拷貝
即:a.str != b.str
a.obj != b.obj
為什么說在 class A這個層級實現了深拷貝,而不是就是深拷貝了呢?
因為 A中的對象 C ,它的默認拷貝實現是深拷貝還是淺拷貝得看它的變量類型以及拷貝實現;