Глыбокае капіраванне або няпоўную копію ў Java - Як выбраць?

Deep_shallow_copy

Глыбокае капіраванне і няпоўную копію

Агляд: У гэтым артыкуле мы разгледзім працэс капіявання аб'ектаў у Java. Мэта капіявання можа адрознівацца ў залежнасці ад патрабаванняў прыкладанняў. Але ёсць у асноўным два тыпу капіявання даступных, глыбокай і дробнай копіі. Метад капіявання змяняецца ў гэтых двух падыходаў.

Увядзенне:
Дзеянне капіявання атрыбутаў аднаго аб'екта ў іншы таго ж тыпу дадзеных, называецца аб'ектам капіявання. У Java, мы маем наступныя падыходы капіявання аднаго аб'екта ў іншы

  • няпоўную копію: Пры гэтым, калі поле, якое павінна быць скапіявана прымітыўны тып, тое значэнне капіюецца інакш, калі поле, якое павінна быць скапіявана з'яўляецца адрасам памяці (або сам аб'ект) то адрас капіюецца. Такім чынам, калі адрас змяняецца адным аб'ектам, змена атрымлівае адлюстраванне ўсюды.
  • Deep Copy: Пры гэтым дадзеныя капіююцца ў абодвух сітуацыях. Такі падыход з'яўляецца больш дарагім і павольней.
  • лянівы Капіяваць: Гэта спалучэнне двух вышэйзгаданых падыходаў. Першапачаткова няпоўны копію падыход выкарыстоўваецца, а затым правяраецца, калі дадзеныя перадаюцца многімі аб'ектамі і праграма павінна змяніць аб'ект, выкарыстоўваецца глыбокі падыход капіявання.

Такім чынам, мы можам выбраць тып капіявання на аснове наступных дзвюх умоў

  • Выкарыстоўвайце неглыбокай капіраванне, калі не патрабуецца герметызацыя.
  • Выкарыстоўвайце глыбокае капіраванне, калі патрабуецца герметызацыя.

няпоўную копію:

У дробнай копіі, новы аб'ект створаны, які змяшчае дакладную копію значэнняў у зыходным аб'екце. Няпоўную копію варта пабітава капіявання падыход. У дробнай копіі, калі поле з'яўляецца адрасам памяці, то адрас капіюецца. Такім чынам, калі адрас змяняецца адным аб'ектам, змена атрымлівае адлюстраванне ўсюды.

Shallow copy

малая копія

Figure 1: Блок-схема апісвае няпоўны копію

На гэтым малюнку, аб'ект – mainObj1 мае поле з імем, як field1 прымітыўнага тыпу кажуць INT, і аб'ект тыпу String, Калі мы робім няпоўны копію mainObj1, mainObj2 ствараецца з field2 тыпу Int, якая ўтрымлівае скапіяваць значэнне field1 але аб'ект тыпу String ў mainObj2 – па-ранейшаму паказвае на objStr сябе. Так як field1 прымітыўны тып дадзеных, значэнне яго капіюецца ў field2. Але так як objStr з'яўляецца аб'ектам, mainObj2 паказвае на той жа адрас objStr. Такім чынам, любыя змены, зробленыя з дапамогай objStr mainObj1 атрымаць адлюстраванне ў mainObj2.

рэалізацыя:

[код]

Listing 1: Клас SubjectVO.java апісвае значэнне аб'екта для суб'ектаў

package com.home.objectCopy;

грамадскасць клас SubjectVO {

прыватны імя Радок;

/**

* @return імя

*/

грамадскасць радок GetName() {

return імя;

}

/**

* @param імя

* імя, каб усталяваць

*/

грамадскасць анулявання SetName(імя Радок) {

this.Імя = імя;

}

грамадскасць SubjectVO(імя Радок) {

this.Імя = імя;

}

}

[/код]

Listing 2: Клас PupilVO.java які апісвае значэнне аб'екта для вучня

[код]

package com.home.objectCopy;

грамадскасць клас PupilVO інвентар Cloneable {

// змяшчаецца аб'ект

прыватны SubjectVO Subj;

прыватны імя Радок;

/**

* @return the Subj

*/

грамадскасць SubjectVO getSubj() {

return Subj;

}

/**

* @param Subj

* the Subj ўсталяваць

*/

грамадскасць анулявання setSubj(SubjectVO Subj) {

this.Subj = Subj;

}

/**

* @return імя

*/

грамадскасць радок GetName() {

return імя;

}

/**

* @param імя

* імя, каб усталяваць

*/

грамадскасць анулявання SetName(імя Радок) {

this.Імя = імя;

}

грамадскасць PupilVO(імя Радок, радок суб) {

this.Імя = імя;

this.Subj = новае SubjectVO(на поўдзень);

}

грамадскасць клон аб'екта() {

// няпоўную копію

старацца {

return супер.клон();

} злавіць (CloneNotSupportedException е) {

return нулявы;

}

}

}

[/код]

Listing3: Клас ShallowCopyTest.java апісання працэсу капіявання

[код]
package com.home.objectCopy;

грамадскасць клас ShallowCopyTest {

грамадскасць статычны анулявання асноўнай(Радок[] аргументы) {

// арыгінальны аб'ект

PupilVO шпілька = новае PupilVO(“Johnathan”, “алгебра”);

Сістэма.з.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());

}

}

[/код]

выхад: Выснова гэтай праграмы ў адпаведнасці з

арыгінальны аб'ект: Johnathan – алгебра

кланаванне аб'екта: Johnathan – алгебра

Арыгінал аб'екта пасля таго, як яна абнаўляецца: Данііл – фізіка

Кланаванне аб'ектаў пасля абнаўлення зыходнага аб'екта: Johnathan – фізіка

Тут мы бачым, што значэнне імя поля атрымлівае змянілася пасля аперацыі капіявання, але кошт прадмета аб'екта застаецца такім жа, як ён паказвае на той жа адрас памяці. Таму прадметам Джонатана становіцца "Фізіка’ дзе, як гэта павінна быць "Алгебра’ як аб'ект для SubjectVO ў кланаванага аб'екта застаецца нязменным.

Deep Copy:

У глыбокай копіі, не толькі ўсе палі аб'екта капіююцца, усе дынамічна размеркавальнай памяці адрас, які паказаў на гэтае месца таксама капіюецца.

Deep Cpoy

Deep Copy

Figure 2: Дыяграма апісвае глыбокі працэс капіявання

На гэтым малюнку, аб'ект mainObj1 мае поля field1 прымітыўны тып дадзеных кажуць Int, і аб'ект тыпу String, Калі мы робім глыбокую копію mainObj1, mainObj2 ствараецца з field2, які змяшчае скапіяваную значэнне field1 і objStr2 ствараецца, якая ўтрымлівае скапіяваць значэнне objStr1 Такім чынам, любыя змены, зробленыя objStr1 ў mainObj1 ня будзе адлюстроўваць у mainObj2.

рэалізацыя:

Listing4: Клас, які апісвае глыбокую копію

[Code]

package com.home.DeepCopy;

грамадскасць клас PupilVO інвентар Cloneable {

// змяшчаецца аб'ект

прыватны SubjectVO Subj;

прыватны імя Радок;

/**

* @return the Subj

*/

грамадскасць SubjectVO getSubj() {

return Subj;

}

/**

* @param Subj

* the Subj ўсталяваць

*/

грамадскасць анулявання setSubj(SubjectVO Subj) {

this.Subj = Subj;

}

/**

* @return імя

*/

грамадскасць радок GetName() {

return імя;

}

/**

* @param імя

* імя, каб усталяваць

*/

грамадскасць анулявання SetName(імя Радок) {

this.Імя = імя;

}

грамадскасць PupilVO(імя Радок, радок суб) {

this.Імя = імя;

this.Subj = новае SubjectVO(на поўдзень);

}

грамадскасць клон аб'екта() {

// глыбокая копія

PupilVO вучань = новае PupilVO(імя, subj.getName());

return вучань;

}

}

[/код]

Адзінае адрозненне паміж гэтым падыходам і раней падыходу заключаецца ў тым, што метад кланавання ў PupilVO вяртае зноў створаны аб'ект PupilVO. Гэта гарантуе, што кожны раз, калі механізм капіявання ў ініцыяваная, аб'ект SubjectVO таксама атрымлівае зменены. Глыбокая копія мае альтэрнатыўны падыход – серыялізацыя. У серыялізацыі, ўвесь аб'ект граф запісваецца ў пастаяннае сховішча і чытаць назад пры неабходнасці. Таму, калі мы чытаем аб'ект з пастаяннага сховішчы, зыходны аб'ект называецца.

Выкарыстанне дробнай копіі і глыбокай копіі:

Там няма жорсткіх правілаў, вызначаныя для выбару паміж дробнай копіі і глыбокай копіі, але, як правіла, мы павінны мець на ўвазе, што калі аб'ект мае толькі прымітыўныя поля, то, відавочна, мы павінны пайсці на дробнай копіі, але калі аб'ект мае спасылкі на іншыя аб'екты, затым на аснове патрабаванняў, няпоўную копію або глыбокай копіі павінна быць зроблена. Калі спасылкі не абнаўляецца, то няма ніякага сэнсу, каб пачаць глыбокую копію.

Растлумачце лянівы копію:

Лянівы копія можа быць вызначана як камбінацыя абодвух дробнай копіі і глыбокай копіі. Механізм варта просты падыход – ў пачатковым стане, выкарыстоўваецца няпоўны копію падыход. Лічыльнік таксама выкарыстоўваецца, каб пастаянна адсочваць, як шмат аб'ектаў падзяляюць дадзеныя. Калі праграма хоча змяніць зыходны аб'ект, ён правярае, ці падзяляе аб'ект або няма. Калі аб'ект з'яўляецца агульным, то глыбокі механізм капіявання ініцыюецца.

Summary:

У дробнай копіі, толькі поля прымітыўнага тыпу дадзеных капіююцца ў той час як спасылкі аб'екты не капіююцца. Глыбокая копія ўключае ў сябе копію прымітыўнага тыпу дадзеных, а таксама Objet спасылкі. Там няма жорсткіх правілаў адносна таго, калі рабіць няпоўны копію і калі рабіць глыбокую копію. Лянівы копія ўяўляе сабой спалучэнне абодвух гэтых падыходаў.

Tagged on:
============================================= ============================================== Buy best TechAlpine Books on Amazon
============================================== ---------------------------------------------------------------- electrician ct chestnutelectric
error

Enjoy this blog? Please spread the word :)

Follow by Email
LinkedIn
LinkedIn
Share