热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java克隆对象_简单了解Java中的克隆

简介在我们日常的工作中,会进行一些Java基础知识的学习,在前段时间学习的就是有关Java中的克隆,下面我们对克隆做简单的介绍。正文Jav
dd785770cd201adf396ef46ae8fef6a9.png

简介

在我们日常的工作中,会进行一些Java基础知识的学习,在前段时间学习的就是有关Java中的克隆,下面我们对克隆做简单的介绍。

正文

Java中的克隆分为两种,一种我们叫做浅克隆(浅复制),一种叫做深克隆(深复制)

1.浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址

第一步:定义一个student类,并实现Cloneable接口(teacher类同student相同,不贴代码)

//克隆的对象必须实现Cloneable这个接口,而且需要重写clone方法
public class Student implements Cloneable {private int age;//定义为private说明这个成员变量只能被被当前类中访问,如果外部需要获得,那么就只能通过getAge方法进行获取private String name;private Teacher teacher;public int getAge(){return age;}public void setAge(int age){this.age = age;}public String getName(){return name;}public void setName(String name){this.name = name;}public Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age &&Objects.equals(name, student.name) &&Objects.equals(teacher, student.teacher);}@Overridepublic int hashCode() {return Objects.hash(age, name, teacher);}@Overridepublic Object clone() throws CloneNotSupportedException{Object object = super.clone();return object;}
}

第二步:创建一个调用的测试类:

public class Demo {public static void main(String[] args) {try{Student student = new Student();student.setAge(18);student.setName("这就是我");Teacher teacher = new Teacher();teacher.setAge(55);teacher.setName("我是老师");student.setTeacher(teacher);Student student2 = (Student)student.clone();//这个是调用下面的那个方法,然后把这个这个对象Clone到studentSystem.out.println("Age:" + student2.getAge() + " " + "Name:" + student2.getName());student.setName("我还是那个我");teacher.setName("我还是那个老师");System.out.println("teacherName:"+student2.getTeacher().getName());}catch (Exception e){e.printStackTrace();System.out.println("报错了");}}
}

通过上面的代码,我们可以得到我们上面对“浅克隆”的描述,指向原有的内存地址。结果如下:

f45eb78aef1d99ffb3d514c66ba9568d.png

我们通过对上面的student中的属性先进行赋值,然后进行clone,然后在重新为teacher中的name赋值,为student中的name赋值,我们得到上面的结果“非基本类型属性,还是指向原来的内存地址”,这样会导致我们在使用过程中出现数据错乱的情况。

2.深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

第一步:还是创建上面的student类,只是重写上面的clone()方法(这里只贴重写的clone方法)

@Overridepublic Object clone() throws CloneNotSupportedException{Student o = null;try {o = (Student) super.clone();} catch (CloneNotSupportedException e) {System.out.println(e.toString());}o.teacher = (Teacher) teacher.clone();return o;}

第二步:创建一个调用的测试类(这里只贴main()方法)

public static void main(String[] args) {try{Student student = new Student();student.setAge(18);student.setName("这就是我");Teacher teacher = new Teacher();teacher.setAge(55);teacher.setName("我是老师");student.setTeacher(teacher);Student student2 = (Student)student.clone();student.setName("我还是那个我");teacher.setName("我还是那个老师");System.out.println("Age:" + student2.getAge() + " " + "Name:" + student2.getName());System.out.println("teacherName:"+student2.getTeacher().getName());}catch (Exception e){e.printStackTrace();System.out.println("报错了");}}

我们还是进行浅克隆中的赋值操作,克隆完成后,对原对象进行赋值,修改源对象的内容,但是我们会发现,我们得到的结果没有发生变化,下面是操作结果

2e24c77b90d9121a93e51248a5187b32.png

总结:

实现Cloneable接口并重写clone接口只能进行浅克隆。但是如果类的引用类型属性(以及属性的引用类型属性)都进行浅克隆,直到没有引用类型属性或者引用类型属性为null时,整体上就形成了深克隆。既对象的引用类型属性和属性的应用类型属性都实现Coloneable,重写clone方法并在clone方法中进行调用。

在选择深克隆方法时,应根据对象的复杂成都,如引用类型属性是否有多层引用类型属性关系。如果对象只有一层或者两层引用类型的属性,选择上面提到的方法较为方便,反之则使用对象流。



推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
双子-殇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有