clone:用于两个对象有相同的内容时,进行复制操作。

提示:Java中要想自定义类的对象可以被复制,自定义类就必须实现Cloneable中的clone()方法。

浅复制:另一个对象用clone()方法对已经存在的对象进行复制的时候,会改变被复制对象里面所有的内容,换句话说,浅复制就是对对象的复制出现了一些问题。

深复制:另一个对象对已有的对象进行相同的内容复制的时候,不会改变原对象的内容

什么情况下会出现浅复制呢?用下面的例子进行说明:

学生类:

  1. public class Student implements Cloneable {
  2.  
  3. private String name;
  4.  
  5. private int age;
  6.  
  7. private Professor professor;
  8.  
  9. public String getName() {
  10. return name;
  11. }
  12.  
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16.  
  17. public int getAge() {
  18. return age;
  19. }
  20.  
  21. public void setAge(int age) {
  22. this.age = age;
  23. }
  24.  
  25. public Professor getProfessor() {
  26. return professor;
  27. }
  28.  
  29. public void setProfessor(Professor professor) {
  30. this.professor = professor;
  31. }
  32.  
  33. @Override
  34. public String toString() {
  35. return "Student [name=" + name + ", age=" + age + ", professor="
  36. + professor + "]";
  37. }
  38.  
  39. public Object clone() throws CloneNotSupportedException{
  40. return super.clone();
  41. }
  42.  
  43. }

  教授类:

  1. public class Professor {
  2.  
  3. private String name;
  4.  
  5. private int age;
  6.  
  7. public String getName() {
  8. return name;
  9. }
  10.  
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14.  
  15. public int getAge() {
  16. return age;
  17. }
  18.  
  19. public void setAge(int age) {
  20. this.age = age;
  21. }
  22.  
  23. @Override
  24. public String toString() {
  25. return "Professor [name=" + name + ", age=" + age + "]";
  26. }
  27.  
  28. }

 案例一: 

  1. public class ShadowCopy {
  2.  
  3. public static void main(String[] args) {
  4. Professor p1 = new Professor();
  5. p1.setName("Professor Zhang");
  6. p1.setAge(30);
  7.  
  8. Student s1 = new Student();
  9. s1.setName("xiao ming");
  10. s1.setAge(18);
  11. s1.setProfessor(p1);
  12.  
  13. System.out.println(s1);
  14.  
  15. try {
  16. Student s2 = (Student) s1.clone();
  17. Professor p2 = s2.getProfessor();
  18. p2.setName("Professor Li");
  19. p2.setAge(45);
  20. s2.setProfessor(p2);
  21. System.out.println("复制后的:s1 = " + s1);
  22. System.out.println("复制后的:s2 = " + s2);
  23. } catch (CloneNotSupportedException e) {
  24. e.printStackTrace();
  25. }
  26.  
  27. }
  28.  
  29. }

  运行结果1:

  1. 1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  2. 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
  3. 3 复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]

  s1的导师为30岁的Professor Zhang,恰巧s2与s1同名同岁,但是s2的导师为45岁的Professor Li,于是我们直接复制s1给s2,再修改下s2的导师的信息。可是,问题出现了,当我们修改了s2的导师后,s2的信息是正确的,但是s1的导师信息也跟着修改了。

案例二:

  1. public class ShadowCopy {
  2.  
  3. public static void main(String[] args) {
  4. Professor p1 = new Professor();
  5. p1.setName("Professor Zhang");
  6. p1.setAge(30);
  7.  
  8. Student s1 = new Student();
  9. s1.setName("xiao ming");
  10. s1.setAge(18);
  11. s1.setProfessor(p1);
  12.  
  13. System.out.println(s1);
  14.  
  15. try {
  16. Student s2 = (Student) s1.clone();
  17. s2.setName("xiao hong");
  18. s2.setAge(17);
  19. Professor p2 = s2.getProfessor();
  20. p2.setName("Professor Li");
  21. p2.setAge(45);
  22. s2.setProfessor(p2);
  23. System.out.println("复制后的:s1 = " + s1);
  24. System.out.println("复制后的:s2 = " + s2);
  25. } catch (CloneNotSupportedException e) {
  26. e.printStackTrace();
  27. }
  28.  
  29. }
  30.  
  31. }

  运行结果二:

  1. 1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  2. 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
  3. 3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

  这次,我们在clone后,又修改了s2的name和age,从结果可以看出,s1的name和age并没有因为s2的修改而改变。

  以上出现的两种情况,就是我们所说的浅复制,但我们实际上不希望出现这两种问题,如何解决呢?那我们必须就要进行深复制。接下来就是我要说的深复制

  1. public class Professor implements Cloneable {
  2.  
  3. private String name;
  4.  
  5. private int age;
  6.  
  7. public String getName() {
  8. return name;
  9. }
  10.  
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14.  
  15. public int getAge() {
  16. return age;
  17. }
  18.  
  19. public void setAge(int age) {
  20. this.age = age;
  21. }
  22.  
  23. @Override
  24. public String toString() {
  25. return "Professor [name=" + name + ", age=" + age + "]";
  26. }
  27.  
  28. public Object clone() throws CloneNotSupportedException{
  29. return super.clone();
  30. }
  31.  
  32. }

  

  1. public class Student implements Cloneable {
  2.  
  3. private String name;
  4.  
  5. private int age;
  6.  
  7. private Professor professor;
  8.  
  9. public String getName() {
  10. return name;
  11. }
  12.  
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16.  
  17. public int getAge() {
  18. return age;
  19. }
  20.  
  21. public void setAge(int age) {
  22. this.age = age;
  23. }
  24.  
  25. public Professor getProfessor() {
  26. return professor;
  27. }
  28.  
  29. public void setProfessor(Professor professor) {
  30. this.professor = professor;
  31. }
  32.  
  33. @Override
  34. public String toString() {
  35. return "Student [name=" + name + ", age=" + age + ", professor="
  36. + professor + "]";
  37. }
  38.  
  39. public Object clone() throws CloneNotSupportedException{
  40. Student newStudent = (Student) super.clone();
  41. newStudent.professor = (Professor) professor.clone();
  42. return newStudent;
  43. }
  44.  
  45. }

  再次运行案例一:

  1. 1.Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  2. 2.复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  3. 3.复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]

  

  再次运行案例二:

  1. 1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  2. 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]]
  3. 3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]

  以上就是我们所说的深复制。好好去领悟哦!

  参考博客:https://www.cnblogs.com/acode/p/6306887.html

clone中的浅复制和深复制的更多相关文章

  1. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  2. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  3. Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...

  4. JAVA中浅复制与深复制

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...

  5. Java中的“浅复制”与“深复制”

    复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...

  6. php对象复制、clone、浅复制与深复制实例详解

    php对象复制.clone.浅复制与深复制实例详解 一.用clone(克隆)来复制对象$obj1 = new Object();$obj2 = clone $obj1;clone方法会触发对象里定义的 ...

  7. js中的浅复制和深复制

    浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...

  8. Python中的浅复制、深复制

    参考 https://docs.python.org/3/library/copy.html?highlight=copy%20copy#copy.copy https://en.wikipedia. ...

  9. java基础-浅复制与深复制的理解

    浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...

  10. 也来谈一谈js的浅复制和深复制

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

随机推荐

  1. 【Javascript-基础-ecma6】ecma6学习笔记(持续更新)

    makdown语法手册API String 新特性的方法 基本不支持IE浏览器 String.fromCodePoint(6特性) String.prototype.codePointAt(6特性) ...

  2. MVC 当中 [ValidateAntiForgeryToken] 的作用

     ValidateAntiForgeryToken 防止CSRF(跨网站请求伪造) 用途:防止CSRF(跨网站请求伪造). 用法:在View->Form表单中:<%:Html.AntiFo ...

  3. java 企业门户网站 源码 自适应响应式 freemarker 静态引擎 html5 SSM

    官网 http://www.fhadmin.org/ 系统介绍: 1.网站后台采用主流的 SSM 框架 jsp JSTL,网站后台采用freemaker静态化模版引擎生成html 2.因为是生成的ht ...

  4. SQL引用DAL

    步骤:https://www.cnblogs.com/grom/articles/8981116.html 异常: 解决方案: 执行 ALTER DATABASE [DBName] SET TRUST ...

  5. js 实现内容的展开和收缩

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. Jquery实现表单动态加减、ajax表单提交

    一直在搞Java后台开发,记得刚工作那一两年时间搞过前后端交互开发,用的东西也是五花八门,当时觉得做页面展示给别人看,是很有成就的事情,不过现在感觉自己跟纯前端开发比起来弱爆了,不过如果你的目标是作为 ...

  7. 【大数据实战】Logstash采集->Kafka->ElasticSearch检索

    1. Logstash概述 Logstash的官网地址为:https://www.elastic.co/cn/products/logstash,以下是官方对Logstash的描述. Logstash ...

  8. 扫描算法(SCAN)——磁盘调度管理

    原创 上一篇博客写了最短寻道优先算法(SSTF)——磁盘调度管理:http://www.cnblogs.com/chiweiming/p/9073312.html 此篇介绍扫描算法(SCAN)——磁盘 ...

  9. 微信小程序 微信支付

    微信小程序前端自处理: //时间戳 timeStamp() { return parseInt(new Date().getTime() / 1000) + '' }, //随机数 randomStr ...

  10. (转载)Javascript异步编程的4种方法

    你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排 ...