當使用「=」賦值引用型別的時候,其實是直接賦值該物件的位址,本質還是乙個物件。
而轉殖則是完全創造乙個新的物件出來,有自己的新位址,只是初始化的資料相同。
轉殖屬於淺拷貝。
person p1 =
newperson
("tom",11
);person p2 = p1;
person p3 =
(person) p1.
clone()
;system.out.
println
(p1)
;system.out.
println
(p2)
;system.out.
println
(p3)
;
輸出資訊:
person@74a14482
person@74a14482
person@1540e19d
對於物件或陣列型別,將物件a
賦值給物件b
,然後改變物件b
的屬性,物件a
也會隨之變化。
物件a
和物件b
指向同一塊記憶體,淺拷貝就是拷貝記憶體位址。
需要實現cloneable
介面,重寫clone()
方法。
class
person
implements
cloneable
@override
public string tostring()
';}@override
protected object clone()
throws clonenotsupportedexception
public
static
class
address
@override
public string tostring()
';}}
}
person p1 =
newperson
("tom",11
,new
person.address
("beijing"))
;person p2 =
(person) p1.
clone()
;p2.addr.address =
"shanghai"
;system.out.
println
(p1)
;system.out.
println
(p2)
;
輸出資訊:
person}
person}
深拷貝是指物件b
開闢新的記憶體,將物件a
的各個屬性都複製到新記憶體中,
物件b
的屬性發生變化時,物件a
的屬性不會受影響。
深拷貝相比於淺拷貝速度較慢並且花銷較大。
比較常用的方案有兩種:
繼續使用clone()
方法對其內部的引用型別,再進行一次clone()
。
序列化這個物件,再反序列回來,重新獲取這個新物件。
使用cloneable介面
class
person
implements
cloneable
@override
public string tostring()
';}@override
protected object clone()
throws clonenotsupportedexception
public
static
class
address
implements
cloneable
@override
public string tostring()
';}@override
protected object clone()
throws clonenotsupportedexception
}}
person p1 =
newperson
("tom",11
,new
person.address
("beijing"))
;person p2 =
(person) p1.
clone()
;p2.addr.address =
"shanghai"
;system.out.
println
(p1)
;system.out.
println
(p2)
;
輸出資訊:
person}
person}
其實和淺複製是一樣的道理,在深複製時將address也進行了一次深複製。
使用反序列化
class
person
implements
serializable
@override
public string tostring()
';}public
static
class
address
implements
serializable
@override
public string tostring()
';}}
}
class
cloneutils
catch
(ioexception e)
catch
(classnotfoundexception e)
finally
catch
(ioexception e)}if
(bais != null)
catch
(ioexception e)}if
(ois != null)
catch
(ioexception e)}if
(baos != null)
catch
(ioexception e)}}
return cloneobj;
}}
person p1 =
newperson
("tom",11
,new
person.address
("beijing"))
;person p2 = cloneutils.
deepclone
(p1)
;p2.name =
"jim"
;p2.addr.address =
"shanghai"
;system.out.
println
(p1)
;system.out.
println
(p2)
;
輸出資訊:
person}
person}
JS實現深拷貝 深轉殖 和淺拷貝 淺轉殖
淺拷貝 只複製物件的基本型別,對於引用型別,只是轉殖位址 包含的內嵌的物件或陣列,不再複製副本 引用型別,只是轉殖位址,那麼原物件修改,轉殖後的新物件也會跟著變化,轉殖不徹底 陣列的array.from 方法就是實現的淺拷貝 物件的object.assign 方法也是實現的淺拷貝 深拷貝 複製物件的...
C 淺轉殖與深轉殖(淺拷貝與深拷貝)
介紹 1 淺轉殖 在淺轉殖中,如果原型物件的成員變數是值型別,將複製乙份給轉殖物件 如果原型物件的成員變數是引用型別,則將引用物件的位址複製乙份給轉殖物件,也就是說原型物件和轉殖物件的成員變數指向相同的記憶體位址。簡單來說,在淺轉殖中,當物件被複製時只複製它本身和其中包含的值型別的成員變數,而引用型...
轉殖,淺拷貝和深拷貝整理
如果想轉殖自定義型別 1.實現介面 2.重寫clone方法 author wgsstart creat 2021 03 07 21 57 為什麼cloneable這個介面是空介面呢?空介面也把它叫做標記介面,其實就是只要乙個類實現了這個介面,那麼就標記這個類,是可以進行clone的。class mo...