java对象的深层复制是指java对象a本身被clone成新对象b,同时a的属性也是被clone成新对象,赋值到a的各个属性上去,a与b的相同属性都引用到不同的对象;
java对象的浅层复制是指java对象a本身被clone成新对象b,但a的属性没有被clone处理,只是把a的各个属性所指的对象赋值到b对应的属性上,a与b的相同属性都引用到同一个对象。
我们一般使用到对象复制是对象浅层复制,也就是没有复制属性成新的属性。
一般有三种方法对象的浅度复制:
(1)通过调用对象set方法来实现,属性个数比较少时适用。
(2) 通过复写object.clone来实现。
(3)通过工具类,如spring的beanutils, 属性个数很多时候适用。
另外,如果java对象的属性都是只读类的话,如原始数据类型、数据封装类、string、bigdecimal、biginteger等,那么浅层复制与深层复制达到的效果是一样的。如果属性有date或其他自定的数据类,则一定的小心了,因为这时浅层复制后对象b的属性f1与原始对象a的对应属性f2,都是引用到同一个对象o,如果通过b.f1的方法改了o的值,则修改会影响到a.f1,这时也就会发生互串的情况。以下例子可以说明这个情况。
tv.t:[color=darkblue]thu jan 01 08:16:40 [/color]cst 1970
tv.t1:t1
-------------------------------
tv.t1==tv2.t1:true
tv.t==tv2.t:true
tv.t::[color=darkblue]thu jan 01 08:33:20 [/color] cst 1970
-------------------------------
tv.t1==tv3.t1:true
tv.t==tv3.t:true
tv.t:::[color=darkblue]thu jan 01 16:20:00 [/color] cst 1970
大家可以看出,(1)(2)的代码操作的是tv2、tv3,但是tv的t的值发生了改变。因为t是date类型的,而date是一个可变的类,这样浅层复制就出现属性值互串的情况。
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:[color=darkblue]thu jan 01 08:16:40 [/color]cst 1970
tv.t1:t1
-------------------------------
tv.t1==tv2.t1:true
tv.t==tv2.t:true
tv.t::[color=darkblue]thu jan 01 08:33:20 [/color] cst 1970
-------------------------------
tv.t1==tv3.t1:true
tv.t==tv3.t:true
tv.t:::[color=darkblue]thu jan 01 16:20:00 [/color] cst 1970
大家可以看出,(1)(2)的代码操作的是tv2、tv3,但是tv的t的值发生了改变。因为t是date类型的,而date是一个可变的类,这样浅层复制就出现属性值互串的情况。