`
hxrs
  • 浏览: 25729 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

[转]Java Clone机制

阅读更多

原帖:http://www.blogjava.net/PariScamper/archive/2007/12/12/167233.html(这个好像也是转载别人的, 一时也找不到原帖在哪,就贴这位的吧。)

1          什么是 Clone ,容易实现吗?

简单地说, Clone 就是对于给定的一个对象实例 o ,得到另一个对象实例 o’ o o’

型相同( o.getClass() == o’.getClass() ),内容相同(对于 o/o’ 中的字段 f ,如果 f 是基本数据类型,则 o.f == o’.f ;如果 f 是对象引用,则 o.f == o’.f o.f 指向的对象与 o’.f 指向的对象的内容相同)。通常称 o’ o 的克隆或副本。

       直观上看,似乎很容易为一个类加上 clone 方法:

class A {

       private Type1 field1;

    private Type2 field2;

     …..

    public Object clone() {

              A a = new A();

        a.field1 = a.getField1();

        a.field2 = a.getField2();

        ……

        return a;

    }

}

 

然而,稍加推敲,就会发现这样的实现方法有两个问题:

1.         要想某个类有 clone 功能,必须单独为其实现 clone() 函数,函数实现代码与该类定义密切相关。

2.         即使基类 A 已有 clone() 函数,其子类 ExtendA 若要具备 clone 功能,则必须 override 其基类 A clone() 函数。否则,对类型为 ExtendA 的对象 ea clone() 方法的调用,会执行于类 A 中定义的 clone() 方法而返回一个类型为 A 的对象,它显然不是 ea 的克隆。

2          Java clone 的支持

万类之初的 Object 类有 clone() 方法:

protected native Object clone() throws CloneNotSupportedException;

该方法是 protected 的,显然是留待被子类 override 的。该方法又是 native 的,必然做了

与具体平台相关的底层工作。

事实上,类 Object clone() 方法首先会检查 this.getClass() 是否实现了 Cloneable 接口。

Cloneable 只是一个标志接口而已,用来标志该类是否有克隆功能。

public interface Cloneable {

}

       如果 this.getClass() 没有实现 Cloneable 接口, clone() 就会抛 CloneNotSupportedException 返回。否则就会创建一个类型为 this.getClass() 的对象 other ,并将 this field 的值赋值给 other 的对应 field ,然后返回 other

       如此一来,我们要定义一个具有 Clone 功能的类就相当方便:

1.         在类的声明中加入“ implements Cloneable ”,标志该类有克隆功能;

2.         Override Object clone() 方法,在该方法中调用 super.clone()

class CloneableClass implements Cloneable {

       ……

public Object clone() {

       try {

              return super.clone(); // 直接让 Object.clone() 为我们代劳一切

    } catch (CloneNotSupportedException e) {

              throw new InternalError();

       }

}

}

 

3          Shallow Clone Deep Clone

3.1     Shallow Deep 从何而来

一个具有克隆功能的类,如果有可变( Mutable )类类型的字段 field ,如何为其克隆(副

本)对象 o’ 中的 field 赋值?

       方法一、如 Object clone() 方法所实现:设原始对象为 o ,其克隆对象是 o’ ,执行 o’.field = o.field 。这样, o’.field o.field 指向同一个可变对象 m o o’ 可能会相互影响(一个对象的状态可能会随着另一个对象的状态的改变而改变)。这样的 Clone 称为 Shallow Clone 。这也是 Object clone() 方法的实现方式。

       方法二、将 o.field 指向的可变对象 m 克隆,得到 m’ ,将 m’ 的引用赋值给 o’.field 。这样 o’ o 内容相同,且相互之间无影响(一个对象状态的改变不会影响另一个对象的状态)。这样的 Clone 称为 Deep Clone

       Java Collection 类库中具体数据结构类( ArrayList/LinkedList HashSet/TreeSet HashMap/TreeMap 等)都具有克隆功能,且都是 Shallow Clone ,这样设计是合理的,因为它们不知道存放其中的每个数据对象是否也有克隆功能。 System.arrayCopy() 的实现采用的也是 Shallow Clone

       Deep Clone 对于实现不可变( Immutable )类很有帮助。设一个类包含可变类 M 类型的 field ,如何将其设计为不可变类呢?先为 M 实现 Deep Clone 功能,然后这样设计类 ImmutableClass

class ImmutableClass {

       MutableClass m;

ImmutableClass(MutableClass m) {

       this.m = m.clone(); // 将传入的 m clone 赋值给内部 m

}

public MutableClass getM() {

    return this.m.clone(); // 将内部 m clone 返回给外部

}

}

 

      

3.2     如何实现 Deep Clone

检查类有无可变类类型的字段。如果无,返回 super.clone() 即可;

如果有,确保包含的可变类本身都实现了 Deep Clone

Object o = super.clone(); // 先执行浅克隆,确保类型正确和基本类型及非可变类类型字段内容正确

对于每一个可变类类型的字段 field

       o.field = this.getField().clone();

返回 o

分享到:
评论

相关推荐

    Java中的克隆(Clone)机制

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

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

    Java克隆(Clone)是Java语言的特性之一,本篇文章主要介绍了Java中的Clone机制是如何工作的,需要的朋友可以参考下

    Clone详解.doc

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

    J2SE笔记讲解个人修订(1.1).docx

    1 JAVA认识 2 JAVA数据类型 3 面向对象程序设计 4 JAVA集合 5 JAVA反射机制 6 JAVA注解(ANNOTATION) 7 JAVA中的异常类 ...20 JAVA克隆CLONE(复制) 21 JAVA 网络编程 22 JAVA 其他未归类 23 JNI概述

    java面试题.pdf

    3. Java中垃圾回收的机制是什么? 4. Java中什么是反射? 5. Java中什么是线程安全? 6. Java中抽象类和接口的区别是什么? 7. Java中什么是异常? 8. Java中如何防止对象的clone? 9. Java中什么是泛型? 10. Java...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    java语言程序设计 java编程笔记 由浅入深的笔记 共32份 全套资源.rar

    clone.docx Date日期.docx GC垃圾回收机制.docx instanceof运算符.docx io.docx java基础关键字.docx java命名和数据类型.docx java序列化.docx Math类.docx Object(对象).docx operator(运算符).docx ...

    java面试宝典

    46、java 中实现多态的机制是什么? 12 47、在java 中一个类被声明为final 类型,表示了什么意思? 12 48、下面哪些类可以被继承? 12 49、指出下面程序的运行结果: 【基础】 13 52、关于内部类: 13 53、数据类型...

    Java面试宝典-经典

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    java 面试题 总结

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    Java面试宝典2010版

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    Java面试宝典2017.zip

    23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested ...

    java面试题大全(2012版)

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

    java 面试常问的问题 如何回答

    一. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。...43、Java中的异常处理机制的简单原理和应用。 28 等等........

    Java的反射中一些重要的方法

     Java中有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode、equals、clone、toString、getClass等。其中getClass返回一个Class 对象。Class对象十分特殊。他是...

    Java核心技术II(第8版)

    10.4.5 远程对象与equals、hashCode和clone方法 10.5 远程对象激活 10.6 Web Services与JAX-WS 10.6.1 使用JAX-WS 10.6.2 Web服务的客户端 10.6.3 Amazon的E-Commerce服务 第十一章 脚本、编译与注解处理 11.1 Java...

    基于JAVA的搜索引擎 lucene-2.2.0

    rollbackSegmentInfos = (SegmentInfos) segmentInfos.clone(); // 克隆 } // 默认的删除策略实现类为KeepOnlyLastCommitDeletionPolicy,它只是保证将最近提交删除的索引文件,提交删除动作 // ...

    最新Java面试宝典pdf版

    43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...

Global site tag (gtag.js) - Google Analytics