深复制或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) {

this.名称=名称;

}

公众 SubjectVO(String name) {

this.名称=名称;

}

}

[/码]

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) {

this.SUBJ = SUBJ;

}

/**

* @返回 名字

*/

公众 字符串的getName() {

return 名称;

}

/**

* @param 名称

* 名称来设置

*/

公众 无效 的setName(String name) {

this.名称=名称;

}

公众 PupilVO(String name, 串子) {

this.名称=名称;

this.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) {

this.SUBJ = SUBJ;

}

/**

* @返回 名字

*/

公众 字符串的getName() {

return 名称;

}

/**

* @param 名称

* 名称来设置

*/

公众 无效 的setName(String name) {

this.名称=名称;

}

公众 PupilVO(String name, 串子) {

this.名称=名称;

this.SUBJ = SubjectVO(子);

}

公众 克隆对象() {

// 深拷贝

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

return 瞳孔;

}

}

[/码]

这种方法与前面的方法之间的唯一差别是,在PupilVO克隆方法返回一个新创建PupilVO对象. 这确保了无论何时在复制机制启动, 对象SubjectVO也得到改变. 深拷贝有一种替代方法 – 系列化. 在系列化, 整个对象图被写入一个持久存储并在需要时读回. 所以,每当我们从持久存储读取对象, 原始对象被称为.

浅拷贝和深拷贝使用:

没有为浅拷贝和深拷贝,但通常我们应该牢记之间选择确定没有硬性的规定,如果一个对象有唯一的原始场, 那么很明显,我们应该去浅拷贝, 但是,如果该对象具有到其他对象的引用, 然后根据要求, 浅复制或深拷贝应该做的事. 如果没有更新的参考文献,然后没有点发起深度复制.

解释懒副本:

懒副本可以被定义为浅拷贝和深拷贝两者的结合. 该机制遵循一个简单的方法 – 在初始状态下, 浅拷贝的方法是使用. 计数器也被用于保持对许多对象如何共享的数据的磁道. 当程序需要修改原来的对象, 它检查该对象是否是共享的还是不. 如果对象是共享, 那么深拷贝机制启动.

Summary:

在浅拷贝, 只有基本数据类型的字段被复制,而对象的引用不会被复制. 深拷贝包括基本数据类型的副本,以及客体引用. 没有硬性规定何时做浅复制和何时做一次深层副本. 懒惰拷贝是这两种方法的组合.

Tagged on:
============================================= ============================================== 在亚马逊上购买最佳技术书籍,en,电工CT Chestnutelectric,en
============================================== ---------------------------------------------------------------- electrician ct chestnutelectric
error

Enjoy this blog? Please spread the word :)

Follow by Email
LinkedIn
LinkedIn
Share