`
xiemingmei
  • 浏览: 212390 次
  • 性别: 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_经典多线程编程

    浅层复制与深层复制 - **知识点描述**:复制对象时,有两种主要的方式:浅层复制和深层复制。浅层复制只复制对象的第一层引用,而深层复制会递归地复制所有引用的对象。 - **详细说明**: - **浅层复制**:仅仅...

    Java二进制序列化与克隆快速、高效、自动化.zip

    Kryo 还可以自动执行深层和浅层复制/克隆。这是从对象到对象的直接复制,而不是从对象到字节再到对象的复制。本文档适用于 Kryo 版本 5.x。请参阅4.x 版本的Wiki 。联系方式/邮件列表请使用Kryo 邮件列表来提问、...

    java_javasecore1_day05

    浅层复制与深层复制 #### 描述 - **浅层复制**仅复制对象的引用,因此复制的对象和原对象共享相同的成员变量。 - **深层复制**则会递归地复制对象及其所有成员变量的副本,创建完全独立的新对象。 - 通过了解这...

    iOS面试题及答案

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

    kryo:Java二进制序列化和克隆:快速,高效,自动

    Kryo还可以执行自动的深层和浅层复制/克隆。 这是从对象到对象的直接复制,而不是从对象到字节的复制。 联系人/邮件列表 请使用获取问题,讨论和支持。 请将Kryo问题追踪器的使用限制为错误和增强功能,而不是问题...

    华为技术笔试题.doc

    11. 简述浅克隆和深克隆:浅克隆是对象的浅层复制,深克隆是对象的深层复制。 12. 文件系统的几个类:FileInputStream、FileOutputStream、FileReader、FileWriter 的区别:这些类是 Java 编程语言中的文件输入输出...

Global site tag (gtag.js) - Google Analytics