`
xiemingmei
  • 浏览: 210551 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java对象的深层复制与浅层复制

阅读更多
   Java对象的深层复制是指Java对象A本身被clone成新对象B,同时A的属性也是被clone成新对象,赋值到A的各个属性上去,A与B的相同属性都引用到不同的对象;
   Java对象的浅层复制是指Java对象A本身被clone成新对象B,但A的属性没有被clone处理,只是把A的各个属性所指的对象赋值到B对应的属性上,A与B的相同属性都引用到同一个对象。

   我们一般使用到对象复制是对象浅层复制,也就是没有复制属性成新的属性。
一般有三种方法对象的浅度复制:
(1)通过调用对象set方法来实现,属性个数比较少时适用。
      TestVO a = new TestVO();
     a.setName("xiemingmei");
     a.setBirthPlace("Hunan");

     TestVO b = new TestVO();
     b.setName(a.getName());
     b.setBirthPlace(a.getBirthPlace());

(2) 通过复写object.clone来实现。
     class TestVO implements Cloneable {
     .......

     TestVO clone(){
        return (TestVO)super.clone();
       }
      }

     TestVO a = new TestVO();
     a.setName("xiemingmei");
     a.setBirthPlace("Hunan");

      TestVO b = a.clone();

(3)通过工具类,如spring的BeanUtils, 属性个数很多时候适用。    
    TestVO a = new TestVO();
    a.setName("xiemingmei");
    a.setBirthPlace("Hunan");
   
    TestVO b = new TestVO();
    BeanUtils.copyProperties(a, b);	

另外,如果Java对象的属性都是只读类的话,如原始数据类型、数据封装类、String、BigDecimal、BigInteger等,那么浅层复制与深层复制达到的效果是一样的。如果属性有Date或其他自定的数据类,则一定的小心了,因为这时浅层复制后对象B的属性F1与原始对象A的对应属性F2,都是引用到同一个对象O,如果通过B.F1的方法改了O的值,则修改会影响到A.F1,这时也就会发生互串的情况。以下例子可以说明这个情况。

TestVo tv = new TestVo();
tv.setT1("t1");
tv.setT(new Date(1000000L));
System.out.println("Tv.T:" + tv.getT());
System.out.println("Tv.T1:" + tv.getT1());
System.out.println("-------------------------------");
	
TestVo tv2 = (TestVo)tv.clone();
System.out.println("tv.T1==tv2.T1:" + (tv.getT1() == tv2.getT1()));
System.out.println("tv.T==tv2.T:" + (tv.getT() == tv2.getT()))

(1)tv2.getT().setTime(2000000L);
System.out.println("Tv2.T:" + tv2.getT());
System.out.println("-------------------------------");
		
TestVo tv3 = new TestVo();
BeanUtils.copyProperties(tv, tv3);	
System.out.println("tv.T1==tv3.T1:" + (tv.getT1() == tv2.getT1()));
System.out.println("tv.T==tv3.T:" + (tv.getT() == tv2.getT()));		
(2)tv3.getT().setTime(30000000L);
System.out.println("Tv3.T:" + tv3.getT());
输出结果为:
Tv.T:Thu Jan 01 08:16:40 CST 1970
Tv.T1:t1
-------------------------------
tv.T1==tv2.T1:true
tv.T==tv2.T:true
Tv.T::Thu Jan 01 08:33:20 CST 1970
-------------------------------
tv.T1==tv3.T1:true
tv.T==tv3.T:true
Tv.T:::Thu Jan 01 16:20:00 CST 1970


大家可以看出,(1)(2)的代码操作的是tv2、tv3,但是tv的T的值发生了改变。因为T是Date类型的,而Date是一个可变的类,这样浅层复制就出现属性值互串的情况。

分享到:
评论
7 楼 呆呆DE萌萌 2014-03-12  
第一种情况是浅度复制?是深度复制吧~
6 楼 大江帅 2013-08-28  
ltyjyufo 写道
那深层复制怎么实现阿,楼主这说的只是浅层复制阿,既然浅层复制后对象B的属性F1与原始对象A的对应属性F2,都是引用到同一个对象O,如果通过B.F1的方法改了O的值,则修改会影响到A.F1,这时也就会发生互串的情况,楼主也没有提出解决的方法阿

可用用ObjectOutputStream和ObjectInputStream来实现深层复制
5 楼 xiemingmei 2012-11-07  
ltyjyufo 写道
那深层复制怎么实现阿,楼主这说的只是浅层复制阿,既然浅层复制后对象B的属性F1与原始对象A的对应属性F2,都是引用到同一个对象O,如果通过B.F1的方法改了O的值,则修改会影响到A.F1,这时也就会发生互串的情况,楼主也没有提出解决的方法阿


要分只读类的对象和可写类的对象。对于只读的,没有关系,无需建新对象;对于可写的,则需要用类似以下的代码: ClassO1 b = new ClassO1(); 
BeanUtils.copyProperties(a, b);   再来复制一个对象出来。
4 楼 ltyjyufo 2012-11-03  
那深层复制怎么实现阿,楼主这说的只是浅层复制阿,既然浅层复制后对象B的属性F1与原始对象A的对应属性F2,都是引用到同一个对象O,如果通过B.F1的方法改了O的值,则修改会影响到A.F1,这时也就会发生互串的情况,楼主也没有提出解决的方法阿
3 楼 yljf1314 2012-08-22  
那既然我们一般使用的是浅复制,那如何解决这种问题,实现深复制呢?
2 楼 xiemingmei 2011-06-15  
如果A.F1的内容改变,比如调用A.F1.setX(*),则B.F1.X也会发生变化。
如果A.F1=obj,这是不会对B.F1产生影响的,应为F1的引用变了,这时,A.F1与B.F1所指向的不是同一个对象。
1 楼 yaozhiqiang109 2011-06-15  
浅层复制··如果要是A或者B改变了的话··那两外一个对象会不会改变?

相关推荐

    java_经典多线程编程

    浅层复制只复制对象的第一层引用,而深层复制会递归地复制所有引用的对象。 - **详细说明**: - **浅层复制**:仅仅复制了对象的第一层,对于对象内的对象,仅仅是复制了它们的引用。这意味着如果原始对象中的某个...

    【Python 技巧】copy 模块中 copy() 与 deepcopy() 函数的区别

    copy() 仅复制对象本身,而不对其中的子对象进行复制,如果对原子对象进行修改,那么浅层复制之后的对象也会随着修改。 deepcopy() 是真正意义上的复制,即重新开辟一片空间,经常说的复制实际上就是 deepcopy,深层...

    浅拷贝(浅复制、浅克隆)、深拷贝(深复制、深克隆)实战工程

    当一个类实现了Cloneable接口并重写了`clone()`方法,就可以调用`clone()`来复制对象。默认的`clone()`方法执行的就是浅拷贝。若要实现深拷贝,需要在`clone()`方法内手动复制引用类型的属性。 2. **序列化和反序列...

    JavaScript浅层克隆与深度克隆示例详解

    总结一下,JavaScript 中的浅层克隆适用于只需要简单复制对象表面属性的情况,而深度克隆则适用于需要完全复制对象包括其所有嵌套引用类型的情况。在实际开发中,应根据具体需求选择合适的克隆方法,以避免不必要的...

    Java教程.doc

    clone方法可以制作某个对象的局域性副本,分为浅层clone和深层clone两种。 控制程序流程 Java中的控制程序流程可以通过运算符来实现。运算符可以分为算术运算符、关系运算符、逻辑运算符、赋值运算符、位运算符等...

    层级浅层记忆

    作为机器学习的一种新的尝试,htm算法已经得到了广大学者的追逐与实践,这里通过java来实现htm算法,仅供学习

    OOM分析工具-MemoryAnalyzer.zip

    浅层大小仅考虑对象本身,而保留大小还包括由该对象间接引用的所有对象的总大小。在分析内存泄漏时,保留大小更为关键。 6. **string table 分析**:MAT还可以分析字符串常量池,找出重复或冗余的字符串,这在处理...

    ios面试题锦集chm版

    答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
深层复制:复制引用对象本身。
意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只...

    浅层地热能勘查评价规范

    《浅层地热能勘查评价规范》是中国一项关于浅层地热能资源勘查与评价的技术规范,其正式版为DZ/T 0225-2009。这项规范主要是为了确保在勘查和评价浅层地热能资源时能够统一标准、规范方法,提高勘查评价的准确性和...

    浅层与深度强化学习“漏洞”分析报告PPT

    ### 浅层与深度强化学习“漏洞”分析报告 #### 知识点一:研究背景与应用背景 **研究背景**: 随着人工智能技术的发展,尤其是强化学习领域内的进步,研究者们越来越关注如何提高这些算法的安全性和鲁棒性。本研究...

    java内存管理精彩概述

    对象的内存布局包括实例变量、方法引用等,遵循Java对象模型。 2. **浅层大小、保留大小与弱引用** - **浅层大小**(Shallow Size):一个对象自身的大小,不包括它引用的对象。 - **保留大小**(Retained Size)...

    java_javasecore1_day05

    - **深层复制**则会递归地复制对象及其所有成员变量的副本,创建完全独立的新对象。 - 通过了解这两者之间的差异,可以更好地掌握对象管理策略,尤其是在处理复杂的对象结构时。 ### 6. 流的过滤器 #### 描述 - 流...

    JavaScript 深层克隆对象详解及实例

    浅层克隆只复制对象的顶层属性,如果属性值为引用类型(如对象或数组),则复制的仅仅是引用,而不是属性中的数据。因此,对于嵌套的对象或数组,浅层克隆会导致新旧对象共享内部对象或数组的引用,一个对象的修改会...

    基于计算机软件开发的JAVA编程应用初探.pdf

    Java能够有效地进行高层室内浅层覆盖,提升网络质量。利用Java进行的网络编程,能够充分利用网络带宽,减少延迟,提高数据传输速率,这对于构建高速、稳定的数据通信环境至关重要。 总的来说,Java编程语言凭借其...

    深度学习吴恩达课程笔记(二)-浅层神经网络、深层神经网络

    【深度学习吴恩达课程笔记(二)-浅层神经网络、深层神经网络】涵盖了神经网络的基础知识,包括浅层神经网络的构建与反向传播,激活函数的选择,以及深层神经网络的优势。 首先,浅层神经网络的核心是双层神经网络。...

    《文本分类大综述:从浅层到深度学习》

    "文本分类大综述:从浅层到深度学习" 文本分类是自然语言处理中的基本任务之一。过去十年,深度学习的成功使得该领域的研究激增。为了满足全面和更新综述的需要,本综述从1961年到2020年对文本分类的发展进行了回顾...

    publication-productivity:集成了深层架构和浅层架构的模型

    而"集成了深层架构和浅层架构的模型"可能是指一种混合模型,它结合了深度学习(如神经网络)的复杂处理能力与更简单、计算效率更高的浅层模型(如决策树或支持向量机)。这种融合方法旨在平衡模型的性能和计算资源的...

Global site tag (gtag.js) - Google Analytics