转自:http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html

现在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做特殊处理,如下代码所示:

  1. class Employee implements Cloneable
  2. {
  3. public Object clone() throws CloneNotSupportedException
  4. {
  5. Employee cloned = (Employee) super.clone();
  6. cloned.hireDay = (Date) hireDay.clone()
  7. return cloned;
  8. }
  9. }

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。

java Clone()克隆的更多相关文章

  1. Java clone克隆方法 --深拷贝--浅拷贝 --原型模型

    什么是深拷贝? 什么是浅拷贝? 创建一个对象的方法有几种? 默认的Object方法中的clone是深拷贝还是浅拷贝? 为什么说很多深拷贝都是不彻底的深拷贝? 什么是原型模型,什么是原型模式? 原型模型 ...

  2. Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

    Java对象克隆(Clone)及Cloneable接口.Serializable接口的深入探讨 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的克隆,就不得不说为什么 ...

  3. Java clone() 方法克隆对象——深拷贝与浅拷贝

    基本数据类型引用数据类型特点 1.基本数据类型的特点:直接存储在栈(stack)中的数据 2.引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指 ...

  4. 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet

    原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...

  5. JAVA对象克隆可能会出现的问题

    首先,区分一下拷贝和克隆: 拷贝:当拷贝一个变量时,原始变量与拷贝变量引用的是同一个对象.当改变一个变量所引用的对象,则会对另一个变量造成影响. 克隆:当克隆一个对象时,是重新的创建了和该对象内容相同 ...

  6. 浅谈Objeact.clone克隆(纯个人理解,如有错误请指正)

    现在先来看一下jdk给出的Object.clone源码和注释 /** * Creates and returns a copy of this object. The precise meaning ...

  7. Java基础——克隆

    1.克隆 假设有一个对象object1,在某处又需要一个跟object1一样的实例object2,这两个对象是绝对独立的,不会因为某一个修改另一个随之改变,这样,我们不能直接将对象objec1t的引用 ...

  8. java Clone之深浅拷贝

    要点: 1.浅度拷贝可以不实现Cloneable接口(自动使用Object.clone)或者不重写Cloneable的clone方法. 2.要被深度拷贝的类必须实现Cloneable接口并重写clon ...

  9. php类之clone 克隆

    对象也能被“克隆” 在php5中,对象的传递方式默认为引用传递,如果我们想要在内存中生成两个一样的对象或者创建一个对象的副本,这时可以使用“克隆”. 通过 clone 克隆一个对象 对象的复制是通过关 ...

随机推荐

  1. Java 授权内幕--转载

    在信息安全性领域,授权是世界的的中心,因为它是控制个体(即人.进程和计算机)对系统资源的访问权限的过程.直到最近,在 Java 安全体系结构中相关的问题都是“这段运行中的代码的访问权限是什么?” 随着 ...

  2. WPF组件开发

    在做组件之前,为了适应框架,我们需要有一个基类,并将这个基类打包成一个模板,让大部分组件去使用这个模板. 组件的基类就不多讲了,上篇文章中已经说过了.这是地址: http://www.cnblogs. ...

  3. oracle用户管理实例

    oracle中的用户角色分为预定义角色和自定义角色. 角色是把常用的权限集中起来形成角色. 授权/分配角色命令 grant 权限/角色 to 用户 收回权限命令: revoke 综合案例: 创建一个用 ...

  4. Winform中修改WebBrowser控件User-Agent的方法(已经测试成功)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  5. nodejs 中koa框架下的微信公众号开发初始篇

    最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...

  6. 后缀自动机(SAM)

    *在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符 ...

  7. oracle 过程函数,包的区别和联系

    一.过程与函数区别 1.过程可以有0~N个返回参数,通过OUT or IN OUT参数返回:函数有且仅有1个返回值,通过return语句返回. 2.调用过程时,可做为单独的语句执行:调用函数时,函数必 ...

  8. C# 匿名表达式(Lambda表达式)

    匿名表达式 这次来说说Lambda表达式吧,反正也简单,我也不像其他高手那样强调来强调去,只讲一下方法: 准备条件如下: 第一,匿名表达式必须存在与之对应的委托. 只要存在相对应的委托就可以了.接下来 ...

  9. mysql备份和恢复

    摘自:http://safe.it168.com/a2009/1108/805/000000805490.shtml 要备份数据库" phpbb_db_backup " #mysq ...

  10. 安装ImageMagick扩展出现configure: error: not found. Please provide a path to MagickWand-config or Wand- config program

    安装ImageMagick扩展报错: checking ImageMagick MagickWand API configuration program... checking Testing /u ...