目录

一、什么是克隆

二、为什么要克隆

三、如何克隆

四、深克隆和浅克隆

浅克隆

深克隆


一、什么是克隆

克隆就是依据已经有的数据,创造一份新的完全一样的数据拷贝。

在Java中对象的克隆有深克隆和浅克隆之分。有这种区分的原因是Java中分为基本数据类型和引用数据类型,对于不同的数据类型在内存中的存储的区域是不同的。基本数据类型存储在栈中,引用数据类型存储在堆中。

二、为什么要克隆

克隆的对象可能包含一些已经修改过的属性,保留着你想克隆对象的值,而new出来的对象的属性全是一个新的对象,对应的属性没有值,所以我们还要重新给这个对象赋值。即当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。那么我把这个对象的临时属性一个一个的赋值给我新new的对象不也行嘛?可以是可以,但是一来麻烦不说,二来,大家通过上面的源码都发现了clone是一个native方法,就是快啊,在底层实现的。

三、如何克隆

  1. 对象的类实现Cloneable接口;
  2. 覆盖Object类的clone()方法 (覆盖clone()方法,访问修饰符设为public,默认是protected);
  3. 在clone()方法中调用super.clone();

说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。 
②继承自java.lang.Object类的clone()方法是浅复制,要想实现深克隆须重写super.clone();

四、深克隆和浅克隆

浅克隆

指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。

public class Student implements Cloneable {private int age;private String name;...@Overridepublic String toString() {return "Student [age=" + age + ", name=" + name + "]";}@Overridepublic Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}/*** @param args* @throws CloneNotSupportedException*/public static void main(String[] args) throws CloneNotSupportedException {Student student1 = new Student(20, "张三");Student student2 = (Student) student1.clone();student2.setAge(22);System.out.println("student1:" + student1.getName() + "-->"+ student1.getAge());System.out.println("student2:" + student2.getName() + "-->"+ student2.getAge());}
}
运行结果:
student1:张三-->20
student2:张三-->22 

注意:修改student2的age值 但是没有影响 student1的值

如果对象中有其他对象的引用,浅克隆的话会出现什么问题呢?

class Teacher implements Cloneable {private String name;private Student student;...@Overridepublic String toString() {return "Teacher [name=" + name + ", student=" + student + "]";}@Overridepublic Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}public static void main(String[] args) throws CloneNotSupportedException {Student s1 = new Student();s1.setAge(20);s1.setName("张三");Teacher teacher1 = new Teacher();teacher1.setName("小赵老师");teacher1.setStudent(s1);//为什么会出现以下结果, Teacher中的clone方法Teacher teacher2 = (Teacher)teacher1.clone();Student s2 = teacher2.getStudent();s2.setName("李四");s2.setAge(30);System.out.println("teacher1:"+teacher1);System.out.println("teacher2:"+teacher2);  }
}运行结果:
teacher1:Teacher [name=小赵老师, student=Student [age=30, name=李四]]
teacher2:Teacher [name=小赵老师, student=Student [age=30, name=李四]

注意:teacher1的学生s1原本是张三,再对teache,1克隆后得到teacher2,由于默认super.clone()是浅克隆,所以当前的teacher2中的student实际上就指向teacher1的student,所以得到teacher2的学生为张三,修改为李四后teacher1的学生也对应改变。

深克隆

不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

class Teacher implements Cloneable {private String name;private Student student;...@Overridepublic Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stub//注意以下代码Teacher teacher = (Teacher)super.clone();teacher.setStudent((Student)teacher.getStudent().clone());return teacher;}public static void main(String[] args) throws CloneNotSupportedException {Student s1 = new Student();s1.setAge(20);s1.setName("张三");Teacher teacher1 = new Teacher();teacher1.setName("小赵老师");teacher1.setStudent(s1);Teacher teacher2 = (Teacher)teacher1.clone();teacher2.setName("小明老师");Student s2 = teacher2.getStudent();s2.setName("李四");s2.setAge(30);System.out.println("teacher1:"+teacher1);System.out.println("teacher2:"+teacher2);}}运行结果:
teacher1:Teacher [name=小赵老师, student=Student [age=20, name=张三]]
teacher2:Teacher [name=小明老师, student=Student [age=30, name=李四]]

深克隆后的老师teacher2为新的对象,与之前的teacher1没有丝毫关系!

【克隆】——Object类clone方法彻底剖析相关推荐

  1. Java基础深度总结:Object类-clone方法

    凡心所向,素履所往,生如逆旅,一苇以航. 内容 1.clone概述 2.Cloneable接口 3.clone与new的区别 4.浅拷贝与深拷贝(重点) 5.Object.clone 6.浅拷贝存在的 ...

  2. 面向对象回顾(静态变量、类加载机制/双亲委派模型、Object类的方法、类和对象区别)

    1. 静态变量存在什么位置? 方法区 2. 类加载机制,双亲委派模型,好处是什么? 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务, ...

  3. java面试题27 java中下面哪些是Object类的方法()

    java面试题27 java中下面哪些是Object类的方法() A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果,蒙蔽树下你和我.遇到这种题,我 ...

  4. 【JAVA】Object类的方法简谈

    Object类的方法简谈 Java中所有的类都继承自Object类,那我们今天来探讨一下Object类中的方法 PS:Object源码中,作者那一栏中,出现了这个 package java.lang; ...

  5. 下面属于java的object_在JAVA中,下列哪些是Object类的方法()

    1.clone方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常. 主要是JAVA里除了8种基本类型传 ...

  6. 修饰符private和protected详解以及调用Object类Clone方法报错:clone() has protected access in java.lang.Object的原因及解决方案

    1. 访问修饰符 访问修饰符的权限范围不用多讲,通过如下一张表即可表示,但是使用起来却有很多疑问.public修饰符就不用多讲了,在哪都可以访问:无修饰符的也不用多加分析,就是同包下可以访问.接下来我 ...

  7. 请列举你所知道的Object类的方法并简要说明。

    小白一个 只记得euqals()和toString()方法了-,重新再整理下好咯 Object类是所有类的父类 Object中的方法进行简要的分析 Clone():创建并返回对象的副本 equals( ...

  8. Object类的方法

    前言 Java语言不同于C++语言,是一种单根继承结构语言,也就是说,Java中所有的类都有一个共同的祖先.这个祖先就是Object类. object类的结构 如图可知,Object类有12个成员方法 ...

  9. JAVA-初步认识-第十一章-object类-equals方法覆盖

    一. 现在要谈论equals方法另一个方面.如果不写equals方法,直接用==来比较也是可以的,貌似equals方法有点多余. 现在不比较对象是否相等,而是比较对象中的特定内容,比如说对象的年龄,之 ...

最新文章

  1. MySQL8.0 - 新特性 - 临时表改进
  2. 257. Binary Tree Paths
  3. Adapter模式的好处
  4. 1.1 函数间隔和几何间隔理解1
  5. android之在view中内嵌浏览器的方法
  6. [课程相关]homework-06
  7. phalcon + nginx 混合模式配置
  8. Tensorflow官方文档学习理解 (三)-MNIST
  9. 利用格林函数解泊松方程
  10. J2ME 手机模拟器插件 eclipseme.feature_1.7.9_site.zip
  11. 树莓派安装拼音输入法(此处为谷歌拼音输入法)
  12. 十代主板改win7_微星h410主板装win7系统及bios设置教程(支持10代usb)
  13. 光纤通信(邱昆、王晟版)课后答案
  14. 市场调研报告-固体废物处理市场现状及未来发展趋势
  15. Word,PDF,PPT,TXT之间的转换方法。
  16. 装备购买(BZOJ4004)高斯消元+ 贪心
  17. win32 窗口 绘制矩形
  18. Ubuntu18.04风扇狂转的解决办法
  19. 基于STM32智能窗帘
  20. 计算机职业生涯规划书素材,职业生涯规划书封面素材

热门文章

  1. 随便玩玩-root用户下rm -rf /的后果
  2. word二级标题自动编号,本来应该是2.1,可是却变成1.2,标题不匹配,怎么办
  3. 揭秘黑暗力量:AMD黑盒5400处理器详测(AMDCPU超频)
  4. SpringBoot+Dubbo+环信(即时通信)整合
  5. linux下nexus3修改admin密码,nexus3忘记密码
  6. php假期培训机构,西安PHP暑假技术学习
  7. Linux中read和write函数的用法
  8. .net framework 4.8是什么,用于哪些方面,作用在哪
  9. 美国最极端的经典教育
  10. 网络经济与企业管理(浏览)