浅析Java中clone()方法浅克隆与深度克隆

 更新时间:2017年04月19日 11:15:39   作者:信念随梦  
Java克隆(Clone)是Java语言的特性之一,本篇文章主要介绍了Java中的Clone机制是如何工作的,需要的朋友可以参考下

   现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在Java中也有这么一个概念,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看Java中的Clone机制是如何工作的?

     1. Clone&Copy

     假设现在有一个Employee对象,Employee tobby =new Employee(“CMTobby”,5000),通
常我们会有这样的赋值Employee cindyelf=tobby,这个时候只是简单了copy了一下reference,cindyelf和tobby都指向内存中同一个object,这样cindyelf或者tobby的一个操作都可能影响到对方。

打个比方,如果我们通过cindyelf.raiseSalary()方法改变了salary域的值,那么tobby通过getSalary()方法得到的就是修改之后的salary域的值,显然这不是我们愿意看到的。我们希望得到tobby的一个精确拷贝,同时两者互不影响,这时候我们就可以使用Clone来满足我们的需求。

Employee cindy=tobby.clone(),这时会生成一个新的Employee对象,并且和tobby具有相同的属性值和方法。

      2. Shallow Clone&Deep Clone

Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。

这样,问题就来了咯,以Employee为例,它里面有一个域hireDay不是基本型别的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型别的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:

 这个时候我们就需要进行deep Clone了,对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。我们可以重新定义Clone方法,对hireDay做特殊处理,如下代码所示:

 class Employee implements Cloneable 
{ 
  public Object clone() throws CloneNotSupportedException 
  { 
   Employee cloned = (Employee) super.clone(); 
  cloned.hireDay = (Date) hireDay.clone() 
  return cloned; 
  } 
}

3. Clone()方法的保护机制

在Object中Clone()是被申明为protected的,这样做是有一定的道理的,以Employee

类为例,通过申明为protected,就可以保证只有Employee类里面才能“克隆”Employee对象,原理可以参考我前面关于public、protected、private的学习笔记。

4. Clone()方法的使用

Clone()方法的使用比较简单,注意如下几点即可:

a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable

b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。

希望本篇文章可以帮助到小伙伴们

相关文章

  • 如何在Spring Boot中实现异步处理与并发控制

    如何在Spring Boot中实现异步处理与并发控制

    本文我们将深入探讨如何在Spring Boot中实现异步处理与并发控制,这一过程涉及到异步任务的执行、线程池的配置、以及并发控制的实践,以帮助我们提升应用的性能和响应能力,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • 详解使用Maven构建多模块项目(图文)

    详解使用Maven构建多模块项目(图文)

    这篇文章主要介绍了详解使用Maven构建多模块项目(图文),非常具有实用价值,需要的朋友可以参考下
    2017-09-09
  • shiro之INI配置详解

    shiro之INI配置详解

    这篇文章主要为大家详细介绍了shiro之INI配置的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • java排序算法之_选择排序(实例讲解)

    java排序算法之_选择排序(实例讲解)

    下面小编就为大家带来一篇java排序算法之_选择排序(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Android开发在轮播图片上加入点击事件的方法

    Android开发在轮播图片上加入点击事件的方法

    这篇文章主要介绍了Android开发在轮播图片上加入点击事件的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式

    SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式

    这篇文章主要介绍了SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Java多线程中常见的几个问题

    Java多线程中常见的几个问题

    这篇文章主要介绍了Java多线程中常见的几个问题 ,需要的朋友可以参考下
    2015-05-05
  • springboot配置resilience4j全过程

    springboot配置resilience4j全过程

    这篇文章主要介绍了springboot配置resilience4j全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • idea中使用git合并分支实践

    idea中使用git合并分支实践

    这篇文章主要介绍了idea中使用git合并分支实践,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java中Map循环遍历的五种方法实现

    Java中Map循环遍历的五种方法实现

    本文主要介绍了Java中Map循环遍历的五种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论