今天来学习学习java对象的克隆,在写代码的时候,有时候我们会这样写:对象1=对象2,也就是把对象2赋值给对象1了,但是这样做有个问题,就是如果我们修改了对象2的属性值,对象1的相同属性值也被修改了,反过来亦如此,让我来证明一下:

public class A {
private String msg; public A() {
msg = "Hello";
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
}
}
public class Main {

    public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
System.out.println("a1.msg: " + a1.getMsg());
a1 = a2;
a2.setMsg("World");
System.out.println("a1.msg: " + a1.getMsg());
} }

运行结果:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAALEAAAA2CAIAAAAH/u/yAAADMElEQVR4nO2by3nlIAxGqUsFUY9KmCpoZRZs7vfNNot0kFn4AQiBbYLf/9kkubZlI44B+yrm++vz/fX59/n7o/EHvA9TdwK8EDgBJHACSOAEkMAJIOnqhGcyxljXIdS9cdaMEPuNW8+nkxNjM4nZPsKJuduI/eS62ey7Z6r0en3rifSeO9wznPjJWtLSsKc7Ee6V6qC3JXVjSOLxrrQujDc+32/cR54hHYmnkD7bYWv+F5wIpzXGEJca2OREHPuEO6xxnGAqXO3W2yksQYZEWDd8FrLsbHSqsFM4evrLMxmiPM87OOGZ4o2+kI4WJ0QsZ49fdbTOHZ5JvTlanBgPCIcmwZ0tJiU72WBTnwwmA0F6y2qNdDY/cYMTSpjDp+MNTiSTR2nAbHBiilNwQkxbUco0L/vN0eVxwstMlIb57U6o6TtairVOyNGx4zix6ITYf9ZiVyfE9CCcKF1eFuO5TuRZOMuJJJV7zh0VJ1ab1zR3ZPm76tyRTOrz84K+Y6kBpWeKqhOya/IrSVce3daYVSfypV92nXM7GtaY4ryXXWPGSy7iyYvaFCubkvVNdFB48CD2cfA8sMh8+qCq3cENTog3jeJC1SZHd0i+Oo2PrG/N9zj+YfRp33dc9T3QnXiWE86WXh+B9dzfiWSkfch79XO5vxOgN3ACSOAEkMAJIIETQAIngAT1mMezoR5TKRHaH9RjKqSvy/VPfs/K2rvjS/RQj6miN6Nv79zfiXfVY4aTDN+ADp+mvVOumpy2xF/ibajCigIT+ws7kfL4esy5I6Ilkiy1qldNOmssh3qOvGfVzhaBC03aF9Rj6oyhPRNx/Pu0dblCytkFEVfWWXUsMV0J6jF1hosZjZ3/GE+3qkJuMROKE1qLji+qQT1m5bqmQWz4mawx4MQL6zGdNdbO8ZnI2lAUt6ZqssWJW80d76vHTFeznikJvaJqsskJ0aKLrzFfVY85xRXXWv7nwGSTmovCccrxcYuGZ1Gl2XvytO87UI/5e57lBOoxe3B/J1CP2Zv7OwF6AyeABE4ACZwAEjgBJHACSOAEkMAJIIETQAIngAROAAmcABI4ASRwAkj+AwAfdXKdITa0AAAAAElFTkSuQmCC" alt="" />

从Main类可以看到,一开始我们new了两个对象,也就是在JVM堆内存开辟了两块内存空间,接着把a2赋值给a1,这就意味着a2和a1对象指向了栈内存中同一个引用,这个时候我们修改a2对象的属性,a1对象的属性也同时会改变,反过来亦如此,例如我现在修改a1的属性来试试看a2的属性是否被改变了:

public class Main {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
System.out.println("a1.msg: " + a1.getMsg());
a1 = a2;
a1.setMsg("Java");
System.out.println("a2.msg: " + a2.getMsg());
}
}

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKkAAAAyCAIAAACoFmz4AAADHklEQVR4nO2a2YGFIAxFqYuCqIcSpgqaoZg3Hy5AAsgmisn9mxERciDm4RW/mP5YBCSi7FkUxOzpitnTFbOnK2ZPVyPYWy2FEMoM6GptGSV2SW0rrz6gPvb7dKTW6hPsTzxS22NNi+p1bbXM0M1fnalBOd98g/0PzaRlYl9h79Z+NlnVhGjvUup9lynj8ofF7fY28AlhBj26tKhBbZwv2LvHCiGkTk2wib3f94ydVLfvtUyMqnZ7uBJhm7Ay2/9cNI3yHuUaubuPv6yWQkoczxvYWy39izYRjhb2oC+jJlQFlTnfahld7C3s9xvcrUHnRiUnjx62rZoxkQo2drgFY5M0Cj+4gX2km/tfo9fsg6SfSnQN7I9+EuzB68YLTWz9jXuHpve9hZFIped69tHw3Q7/gj3MagP3/SV70P7Efyt7kNYB+9TwUB/rs8ezfYp9ELI7c36GffEKa8r5KH5P5/zgpXvW5/GGqYGmavgse4gAjySsDIbVeln2uARD4zzn0VDrgec+Xuv5pY/UB//cKxAOGTHwbnKFvtTW7xx3DCIc/gCM7cgG9uDkDQw0OmVvJ+Aq0b8zfxW3mPAj7yPn+a85L1lJn2BvVOqYhZXRsuyDDPmR8+TJWpY9q1vMnq6YPV0xe7pi9nTF7OlqAHt30MU/spdSJ/vggHv7o39MzytyAPvBI4Rur2YYk9injZVV/N12RQ3y6x0q+fD4br8eGmvSThJ0Db12fsuth8pITtAgv96m8nP19/r10DjTM4LRCIa8N0g9/iKSUzTIr/dLfMrO9PNSvx4aZ2Y1o6tBCPIBecHbZJBfrzb6b/XrwWUVo5uJhp+6UBYoi+REjfDrNRiK3+rXy7O/joYbJ0Rf6nycqF6/XsqjfqG3+vUiFeU5pDL34v6uAqVPufNxorr8emF1tt8Q8RxGa/h3+vXQgUXo1itwLxolhJJwMRY7Hyeqy68X9aBdsn+vXw91nfAexqMRNkqNJ3/vVH3kPJ/9eg36BHv26zVpWfbs1+vWsuxZ3WL2dMXs6YrZ0xWzpytmT1fMnq6YPV0xe7pi9nT1DywNBMGxkHl4AAAAAElFTkSuQmCC" alt="" />

毫无悬念地改变了,也就是说使用“=”操作符会让两个对象指向同一个引用,两个对象的属性值是互通的,一个对象的改变必然会同步到另一个对象上面,但是有时候我们并不想一个对象的改变引起另一个对象的改变,我们希望a2对象被创建后含有a1对象初始的值,但是a2对象属性的改变不会影响a1对象,这样我们就应该使用对象的克隆,对象的克隆又分浅克隆和深克隆,我们先来看看浅克隆的实现方式:

public class A implements Cloneable {
private String msg; public A() {
msg = "Hello";
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
A a1 = new A();
System.out.println("a1.msg: " + a1.getMsg());
A a2 = (A) a1.clone();
System.out.println("a2.msg: " + a2.getMsg());
a2.setMsg("Java");
System.out.println("a1.msg: " + a1.getMsg());
System.out.println("a2.msg: " + a2.getMsg());
}
}

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL8AAABjCAIAAABFdEYFAAAEqklEQVR4nO2czdWcIBhGqYuCrIcSUoWtZOHmOyfbLNKBWYyO8iu8Iw7ivSebb0YR8AqMPlH9+/uz//fn5/cc4heAh8q0B8AHe0AO9oAc7AE52ANy6tgzGa2UGsYTiro346AWtJkKv70BZ9uzdIg2ZujCnvcJ1mZarwpVfGVMRif8SH/bMtVmrrEPe2avJZKGYc/Kdv0lh9ySTl6K1Ga50odxG8Mmf7tlG/cI9jywFjl5G5SeqQN7tsMqpbSJNVBkz77sFq/FT8ceoyPtKr1Et6XSq8uG8fXZdj7GYXeobaNt7/WvyWiltX9GKtgzGb3/cop0h8Qep6xxaHB19PHMNRkdvOAk9iw7bLtahY9DtPu8g728O6evrcHFHgZCjRwH/8ACewLFtLcYkNhjTV2x4Vpgz1pOxB5n0tx1bsjg89YS8bFncnsiNsmU2xPsvub0KbbHHZtPHHsO7XG2fwtU1R5ncnLsiVXPKwN7Qv31LXusTq85cyXsyXZUNHN5/decPMVjj7X4eP9WCm8Ya2rs91TSHvck+jWxV0inrZqT9viLWa+e73YIVs3OcTtYNe8XkdqsBqWWAm6jvbO422n70aXNtC/cL9g5R/bP+dCoILDHuRvsVDTY5N215K+393umv/W3aGzcmeeOn3Pd9g7cnejUnnGI3biDE+nIHmucb3CY75CO7IHLwR6Qgz0gB3tADvaAHOwBOVXs2W6+Pv2mC7nmMqwHP68/Pq/l9yDXnKJCKt7u2NBDw3tBrjlKtVzzSk5nk2sm1xwi/3kTuWb/0+fmmudI1CVRDrnmdDH3T4fNc2auufT8kWtOHTTx4Tepk2sWDLPkmi26tCcj1xyb+w8g12zzxFyzvc5ddgj0QvD3FLnmg+N2sGpO5pqDWd1De8g1h1tFrvlb3PYO3J3o1B5yzZfQkT3kmi+nI3vgcrAH5GAPyMEekIM9IAd7QE4de7awzsMh11zE+2kA72veQTK1kPYeCEsh1xylWq65pJPJNZNrthG8t1CRa7Y/fW6uWWIPueZkMe0tBqrlmmu8M5Vcc2P61Mk1z3XscbYn1/xtzs81L9S2h1xzA5yca7Y2jDWVXHPOtw/MNQeXAryvOVhvcs3tcts7cHeiU3vINV9CR/aQa76cjuyBy8EekIM9IAd7QA72gBzsATlV7OF9zQ/hdHusBz/j7d/XvBJ4rMAtJd7XXEp2KuMJVMs1r+TECtrONXt1jQbWrKLdTPJ+y1cJhT3ZINVyzS/ynze1m2v26hlvkdsbVpWXDWKHl73u8btUyzXPkahLopxGc81ePRPXg/et1QXpDrnhnFgt11x6/lrNNbtihvxI9MZ++PRGoryebJg6ueaO3tectue4N7Z6uvLkJsQb5vxcc+z/NB3Qaq45sDZ/Vykv5b3MuM4SMD8h3jAn55rtde6yw73f1+zdwLJTzRkp73FQatCuztkJ8YY5Odfc2/uavaIjGe1wb9gbxeqT3rdpun3ORa75Ajq1h1zzJXRkD7nmy+nIHrgc7AE52ANysAfkYA/IwR6Qgz0gB3tADvaAHOwBOdgDcrAH5GAPyMEekIM9IAd7QA72gBzsATnYA3L+A3W+QswMrJGcAAAAAElFTkSuQmCC" alt="" />

可以看到实现对象的克隆比较简单,首先该类应该实现Cloneable接口并覆盖Object根类的clone方法,注意Cloneable只是一个标记接口,里面并没有定义任何方法,clone方法里面的实现也很简单,调用父类Object的clone方法就好了。现在看看Main类就知道,a2对象的msg初始化是"Hello",把a2的msg属性的值改为"Java"后,并没有影响a1对象的msg值,其值仍然是"Hello". 我们刚才看到的是浅克隆,没有集合属性,如果有集合属性的话,浅克隆就应付不了这种情况了,我们来看看代码:

public class A implements Cloneable {
private List<String> list; public A() {
list = new ArrayList<String>();
list.add("Hello");
list.add("World");
} public List<String> getList() {
return list;
} public void setList(List<String> list) {
this.list = list;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
A a1 = new A();
System.out.println("a1.list: " + a1.getList());
A a2 = (A) a1.clone();
System.out.println("a2.list: " + a2.getList());
a2.getList().add("Java");
System.out.println("a1.list: " + a1.getList());
System.out.println("a2.list: " + a2.getList());
}
}

aaarticlea/png;base64,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" alt="" />

大家看看,神奇的魔咒又出现了,即使我们实现了对象的克隆,但是因为对象的属性是集合类,这样我们修改a2对象的集合类中的值,也一定会影响a1对象集合类的值, 这是因为a1和a2对象的list属性是指向同一个内存地址的,面对这种情况,我们需要使用到对象的深克隆,具体怎么实现呢,来看代码:

public class A implements Cloneable {
private List<String> list; public A() {
list = new ArrayList<String>();
list.add("Hello");
list.add("World");
} public List<String> getList() {
return list;
} public void setList(List<String> list) {
this.list = list;
} @Override
protected A clone() throws CloneNotSupportedException {
A other = (A) super.clone();
List<String> otherList = new ArrayList<String>();
for (String s : list) {
otherList.add(s);
}
other.setList(otherList);
return other;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
A a1 = new A();
System.out.println("a1.list: " + a1.getList());
A a2 = (A) a1.clone();
System.out.println("a2.list: " + a2.getList());
a2.getList().add("Java");
System.out.println("a1.list: " + a1.getList());
System.out.println("a2.list: " + a2.getList());
}
}

aaarticlea/png;base64,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" alt="" />

大家可以看到,深克隆的实现也就是要在clone方法里面new一个list,并把原来对象list中的值赋值到新list中并把新list设置到新对象,说起来好拗口啊,这样a2.list值得改变不会影响a1.list了,想想如果原始类的属性是一个对象,而对象的属性又有对象和集合类,那么clone方法里面的代码就会很大,因为深克隆必须保证全面的克隆。

Java的“影子克隆”和“深度克隆”的更多相关文章

  1. 如何复制一个java对象(浅克隆与深度克隆)

    在项目中,有时候有一些比较重要的对象经常被当作参数传来传去,和C语言的值传递不同,java语言的传递都是引用传递,在任何一个地方修改了这个对象的值,就会导致这个对象在内存中的值被彻底改变.但是很多时候 ...

  2. Cloneable接口的作用与深度克隆与浅度克隆

    cloneable接口的作用 cloneable其实就是一个标记接口,只有实现这个接口后,然后在类中重写Object中的clone方法,然后通过类调用clone方法才能克隆成功,如果不实现这个接口,则 ...

  3. js对象简单、深度克隆(复制)

    javascript的一切实例都是对象,只是对象之间稍有不同,分为原始类型和合成类型.原始类型对象指的是字符串(String).数值(Number).布尔值(Boolean),合成类型对象指的是数组( ...

  4. Java List的深度克隆

    关于java List的深度克隆 List是java容器中最常用的顺序存储数据结构之一.有些时候我们将一组数据取出放到一个List对象中,但是可能会很多处程序要读取他或者是修改他.尤其是并发处理的话, ...

  5. java中传值及引伸深度克隆的思考(说白了Java只能传递对象指针)

    java中传值及引伸深度克隆的思考 大家都知道java中没有指针.难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址的话简直不可想象! java中内存的分配方式有两种,一种是在堆中分配, ...

  6. java对象 深度克隆(不实现Cloneable接口)和浅度克隆

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt128 为什么需要克隆: 在实际编程过程中,我们常常要遇到这种情况:有一个对象 ...

  7. Java中深度克隆和浅度克隆

    一:使用目的: 就是为了快速构造一个和已有对象相同的副本.如果需要克隆对象,一般需要先创建一个对象,然后将原对象中的数据导入到新创建的对象中去,而不用根据已有对象进行手动赋值操作. 二:Object中 ...

  8. Java的深度克隆和浅度克隆

    说到克隆,其实是个比较简单的概念,跟现实生活正的克隆一样,复制一个一模一样的对象出来.clone()这个方法是从Object继承下来的,一个对象要实现克隆,需要实现一个叫做Cloneable的接口,这 ...

  9. Java的赋值、浅克隆和深度克隆的区别

    赋值 直接  = ,克隆 clone 假如说你想复制一个简单变量.很简单: int a= 5; int b= a; b = 6; 这样 a == 5, b == 6 不仅仅是int类型,其它七种原始数 ...

随机推荐

  1. 合约广告系统-Hadoop

    Hadoop Hadoop 概况 Hadoop 由 Apache Software Foundation 公司于 2005 年秋天作为Lucene的子项目 Nutch的一部分正式引入.它受到最先由 G ...

  2. javascript call()函数

    js中的call()函数,简单的说就是用来纠正指正的吧! 调用一个对象的方法,用另一个对象替换当前对象,这样说显得相当的空洞与抽象,实例说明一切! <script type="text ...

  3. MySQL能够承受上亿万条的数据量的架构

    MySQL能够承受上亿万条的数据量的架构 最近做的搜索引擎的数据量是越来越大估计了下在中国可能涉及到的1Kw的数据量,就全球来说也就是1K亿而已,最初是用的数据库是MySQL现在来说要做些优化,最终使 ...

  4. HTTP协议 HttpWebRequest和 Socket的一点总结

    HTTP协议 HttpWebRequest和 Socket的一点总结 相信接触过网络开发的人对HTTP.HttpWebRequest.Socket这些东西都不陌生吧.它们之间的一些介绍和关系我这里都忽 ...

  5. How to deploy openbr on linux server very shorly---- linuxmint13/ubuntu12.04 AMD64/debian7

    SO FAST ON A SERVER!!!! There are serveral packages that you have to install: 1. openbr 0.6.0 packag ...

  6. hdu 3333 Turing Tree(线段树+离散化)

    刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望. 刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的 ...

  7. HttpURLConnection碰到连续302跳转的问题的原因及解决方法

    用HttpURLConnection联网的代码: HttpURLConnection conn = null;       URL url = new URL("http://10.0.0. ...

  8. 项目中出现黄色感叹号 教你去掉Myeclipse的黄色感叹号

    点击Window>>Preferences>>General>>Editors>>Text Editors>>Annotations 选中右 ...

  9. C语言之while和do-while

    一 while和do-while的简介 1). while语句 语法: while(表达式){ 循环体; } 循环过程: 1.先判断表达式,是否为真,如果为真跳转到2,否则跳转到3 2.执行循环体,执 ...

  10. c++内存对齐 转载

    转载自http://blog.csdn.net/chengonghao/article/details/51674166 例子举的特别好 很多文章大概都有像这样的结论: 1. 数据项只能存储在地址是数 ...