深複製或Java中的淺複製 - 如何選擇?

Deep_shallow_copy

深拷貝和淺拷貝

概觀: 在這篇文章中,我們將討論在複製Java對象的過程. 複製的目的,可以不同基於應用需求. 但主要有兩種類型的複製, 深,淺拷貝. 複製的方法,這兩種方法而變化.

介紹:
複製一個對象的屬性成另一種數據類型相同的動作被稱為對象複製. 在java, 我們有複製一個對象的下列方法到另一

  • 淺拷貝: 這裡,如果要被複製的場是一個基本類型, 然後該值被複製否則,如果要被複製的場是一個存儲器地址 (或對象本身) 然後該地址被複製. 因此,如果地址是由一個對象改變, 變化被處處體現.
  • 深複製: 這裡的數據在這兩個情況下複製. 這種方法是昂貴的和較慢的.
  • 懶惰複製: 這是上述兩種方法的組合. 最初使用的淺拷貝的方法,然後檢查是否該數據是由許多對象共享和程序需要修改對象, 深副本的方法是使用.

因此,我們可以選擇拷貝的基於以下兩個條件的類型

  • 不需要封裝時,使用淺拷貝.
  • 需要封裝時使用深度複製.

淺拷貝:

在淺拷貝, 一個新的對象被創建包含值的原始對象的精確副本. 淺拷貝遵循逐位複製方法. 在淺副本,如果該字段是一個內存地址, 然後該地址被複製. 因此,如果地址是由一個對象改變, 變化被處處體現.

Shallow copy

淺拷貝

Figure 1: 流程圖描述淺拷貝

在該圖, 物體 – mainObj1有一個命名為原始類型的字段1場說INT, 和String類型的對象當我們做mainObj1的淺表副本, mainObj2與int類型的字段2包含FIELD1的複製價值,但在mainObj2 String對象創建 – 仍然指向objStr本身. 由於FIELD1是一個原始數據類型, 它的值複製到域2. 但由於objStr是一個對象, mainObj2指向objStr的同一地址. 因此,通過mainObj1到objStr所做的任何更改都會反映在mainObj2.

履行:

[碼]

Listing 1: 類SubjectVO.java介紹對象的值對象

package com.home.objectCopy;

公眾 SubjectVO {

私人 String name;

/**

* @返回 名字

*/

公眾 字符串的getName() {

return 名稱;

}

/**

* @param 名稱

* 名稱來設置

*/

公眾 無效 的setName(String name) {

這個.名稱=名稱;

}

公眾 SubjectVO(String name) {

這個.名稱=名稱;

}

}

[/碼]

Listing 2: 類PupilVO.java描述瞳孔值對象

[碼]

package com.home.objectCopy;

公眾 PupilVO 器物 可複製 {

// 包含的對象

私人 SubjectVO SUBJ;

私人 String name;

/**

* @返回 the SUBJ

*/

公眾 SubjectVO getSubj() {

return SUBJ;

}

/**

* @param SUBJ

* the SUBJ 設置

*/

公眾 無效 setSubj(SubjectVO SUBJ) {

這個.SUBJ = SUBJ;

}

/**

* @返回 名字

*/

公眾 字符串的getName() {

return 名稱;

}

/**

* @param 名稱

* 名稱來設置

*/

公眾 無效 的setName(String name) {

這個.名稱=名稱;

}

公眾 PupilVO(String name, 串子) {

這個.名稱=名稱;

這個.SUBJ = SubjectVO(子);

}

公眾 克隆對象() {

// 淺拷貝

嘗試 {

return 非常.克隆();

} (CloneNotSupportedException的ê) {

return ;

}

}

}

[/碼]

Listing3: 類ShallowCopyTest.java描述複製過程

[碼]
package com.home.objectCopy;

公眾 ShallowCopyTest {

公眾 靜止 無效 主(串[] 參數) {

// 原始對象

PupilVO螺柱= PupilVO(“喬納森”, “代數”);

系統..調用println(“原始對象: ” + stud.getName() + ” – ”

+ stud.getSubj().的getName());

// 克隆對象

PupilVO clonedStud = (PupilVO) stud.clone();

系統..調用println(“克隆的對象: ” + clonedStud.getName() + ” – ”

+ clonedStud.getSubj().的getName());

stud.setName(“丹尼爾”);

stud.getSubj().的setName(“物理”);

系統..調用println(“原始對象被更新後: ”

+ stud.getName() + ” – ” + stud.getSubj().的getName());

系統..調用println(“更新原來的對象後,克隆的對象: ”

+ clonedStud.getName() + ” – ”

+ clonedStud.getSubj().的getName());

}

}

[/碼]

產量: 這個程序的輸出是下

原始對象: 喬納森 – 代數

克隆的對象: 喬納森 – 代數

原始對象被更新後: 丹尼爾 – 物理

更新原來的對象後,克隆的對象: 喬納森 – 物理

在這裡,我們看到的字段名稱的值被拷貝後改變,但因為它是指向同一個內存地址對象主體的值保持不變. 因此,對於喬納森的主題變成了“物理’ 在那裡,它應該是“代數’ 作為克隆對象SubjectVO的對象保持不變.

深複製:

在深拷貝, 不僅所有對象的字段複製, 所有這一切是由對象指向的動態分配的內存地址也被複製.

Deep Cpoy

深複製

Figure 2: 下圖描述了深拷貝過程

在該圖, 對象mainObj1有field1的領域基本數據類型INT說, 和String類型的對象當我們做mainObj1的深層複製, mainObj2與包含域2 FIELD1的複製價值和objStr2創建包含objStr1的複製價值所以mainObj1到objStr1所做的任何更改將不mainObj2反映創建.

履行:

Listing4: 類描述深拷貝

[Code]

package com.home.DeepCopy;

公眾 PupilVO 器物 可複製 {

// 包含的對象

私人 SubjectVO SUBJ;

私人 String name;

/**

* @返回 the SUBJ

*/

公眾 SubjectVO getSubj() {

return SUBJ;

}

/**

* @param SUBJ

* the SUBJ 設置

*/

公眾 無效 setSubj(SubjectVO SUBJ) {

這個.SUBJ = SUBJ;

}

/**

* @返回 名字

*/

公眾 字符串的getName() {

return 名稱;

}

/**

* @param 名稱

* 名稱來設置

*/

公眾 無效 的setName(String name) {

這個.名稱=名稱;

}

公眾 PupilVO(String name, 串子) {

這個.名稱=名稱;

這個.SUBJ = SubjectVO(子);

}

公眾 克隆對象() {

// 深拷貝

PupilVO瞳= PupilVO(名稱, subj.getName());

return 瞳孔;

}

}

[/碼]

這種方法與前面的方法之間的唯一差別是,在PupilVO克隆方法返回一個新創建PupilVO對象. 這確保了無論何時在複製機制啟動, 對象SubjectVO也得到改變. 深拷貝有一種替代方法 – 系列化. 在系列化, 整個對象圖被寫入一個持久存儲並在需要時讀回. 所以,每當我們從持久存儲讀取對象, 原始對象被稱為.

淺拷貝和深拷貝使用:

沒有為淺拷貝和深拷貝,但通常我們應該牢記之間選擇確定沒有硬性的規定,如果一個對象有唯一的原始場, 那麼很明顯,我們應該去淺拷貝, 但是,如果該對象具有到其他對象的引用, 然後根據要求, 淺複製或深拷貝應該做的事. 如果沒有更新的參考文獻,然後沒有點發起深度複製.

解釋懶副本:

懶副本可以被定義為淺拷貝和深拷貝兩者的結合. 該機制遵循一個簡單的方法 – 在初始狀態下, 淺拷貝的方法是使用. 計數器也被用於保持對許多對象如何共享的數據的磁道. 當程序需要修改原來的對象, 它檢查該對象是否是共享的還是不. 如果對象是共享, 那麼深拷貝機制啟動.

Summary:

在淺拷貝, 只有基本數據類型的字段被複製,而對象的引用不會被複製. 深拷貝包括基本數據類型的副本,以及客體引用. 沒有硬性規定何時做淺複製和何時做一次深層副本. 懶惰拷貝是這兩種方法的組合.

標籤:
============================================= ============================================== 在亞馬遜上購買最佳技術書籍,en,電工CT Chestnutelectric,en
============================================== ---------------------------------------------------------------- electrician ct chestnutelectric
error

Enjoy this blog? Please spread the word :)

Follow by Email
LinkedIn
LinkedIn
Share