今天来学习学习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. jQuery event的复制粘贴的坑

    jQuery为了兼容性会把系统暴露出来的event重新整理一遍,但是复制粘贴的event就被丢掉了. 所以要在所有原生浏览器想实现复制粘贴,大家都用flash实现了.其实只要用原生的方法捕获事件就ok ...

  2. 关于在Java EE 下开发web,出现项目中的外部包没有tomcat的包的原因

    在新建的项目的时候,要设置目标服务器运行环境,把那个设置成tomcat,这样,项目中就会有tomca的api

  3. 利用ie的behavior属性兼容css3的一些属性

    behavior是从Internet Explorer 5开始引入的,是一种通过使用 CSS 向 HTML 元素添加行为的方法. 但是只有 Internet Explorer 支持 behavior ...

  4. ASP.NET MVC4简单使用ELMAH记录系统日志

    ASP.NET MVC4简单使用ELMAH记录系统日志 前言 在项目开发.测试以及已经上线的项目中都会存在bug,而如果我们在项目的各个阶段都能及时的监控系统出现的任何问题,那么对于我们开发人员来说完 ...

  5. .Net项目框架

    摘要:本文描述了在用VS.NET进行B/S开发时采用的框架结构,一般建立类库项目和Web项目,在Web基本aspx页面类中调用类库中方法,同时在aspx页面类中不需要写任何对数据库操作的SQL代码,便 ...

  6. zoj1537- Playing with a Calculator

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=537 题意:给你一个k值,现在要你求一个最小的N 值,N每一个数位上的数值a均相 ...

  7. 汇编条件判断整理(JCC,CMP/TEST的实现)

    比较的实现 我们知道CMP是比较两个寄存器内容的指令,但这是如何实现的? 当执行到CMP指令的时候会读取这两个寄存器的内容,并加以减法运算,结果本身不保留,并按照结果设置符号位(属算术运算). CMP ...

  8. EF 下的code fist 模式编程

    EF 分两种模式 codefirst(就是不知道数据是啥,也没有数据库)  和 database fist (数据已经设计好了) 首先打开vs  新建一个项目 创建一个控制台程序 然后 新建一个Tea ...

  9. bzoj3504: [Cqoi2014]危桥 网络流

    一种网络流建图的思路吧,改天最好整理一波网络流建图思路 #include <bits/stdc++.h> using namespace std; int n,h,t,a1,a2,an,b ...

  10. The Linux Mint 18.1:Eclipse Run The C++ And Python ConfigorationWhen You achieve above step,you can run the c++ and python! (Next OTL ,PYOTL is Project That Write By Ruimin Shen(ability man) )

    # Copyright (c) 2016, 付刘伟 (Liuwei Fu)# All rights reserved.# 转载请注明出处 1.Install The Eclipse,g++ Use T ...