`
hxrs
  • 浏览: 26312 次
  • 性别: 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`机制提供了复制对象的能力,通过实现`Cloneable`接口和覆盖`clone`方法,我们可以创建对象的副本,同时保证原对象不受影响。根据需求的不同,可以选择浅克隆或深克隆来处理对象及其引用的复杂性...

    Java Clone(类的复制)实例代码

    在Java编程语言中,`Clone`机制是一种对象复制的方式,允许创建一个现有对象的副本。在Java中,对象的默认复制是浅复制(shallow copy),这意味着只复制对象本身,而不复制它引用的对象。要实现深复制(deep copy)...

    java中的指针,引用及对象的clone

    本文将深入探讨Java中的引用以及对象的克隆机制,包括浅拷贝和深拷贝的区别及其应用场景。 #### 二、Java中的引用 在Java中,当使用`new`关键字创建一个对象时,实际上创建的是一个指向该对象的引用。例如,以下...

    Java clone方法详解及简单实例

    Java中的`clone`方法是Java语言提供的一种复制对象的机制,它允许创建一个现有对象的副本,这个副本具有与原始对象相同的状态,但它们是独立的实体,对其中一个对象的修改不会影响另一个。`clone`方法是Java `Object...

    Java Clone深拷贝与浅拷贝的两种实现方法

    Java Clone 是 Java 语言中的一种复制对象的机制,它可以将一个对象的所有属性和状态复制到另一个对象中,实现对象的深拷贝和浅拷贝。下面我们将讨论 Java 中的深拷贝和浅拷贝的两种实现方法。 一、浅拷贝 浅拷贝...

    Java中的clone方法详解_动力节点Java学院整理

    下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 clone方法顾名思义,就是复制,在Java语言中,clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源...

    如何通过JVM角度谈谈Java的clone操作

    首先,让我们理解`clone`方法的工作机制。在Java中,`clone`方法是`Object`类的一个受保护的方法,这意味着所有Java对象都隐含地继承了这个方法。然而,`Object`类的`clone()`方法执行的是浅克隆,即如果对象包含...

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

    Java中的克隆(Clone)机制是面向对象编程中一种创建对象副本的方法,它允许程序员创建一个已有对象的新实例,新实例的数据与原对象相同。在Java中,克隆分为两种类型:浅克隆(Shallow Clone)和深度克隆(Deep ...

    JAVA_高级特性(hashCode,clone,比较器,Class反射,序列化)

    ### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。

    Clone详解.doc

    Java中的克隆(Clone)机制是一种创建对象副本的方法,它允许程序员复制一个对象的状态,而不会影响原始对象。克隆在编程中常用于创建对象的独立副本,使得新副本与原对象之间相互独立,对其中一个对象的修改不会...

    java-6个机制.doc

    Java的六个核心机制是编程中不可或缺的部分,它们包括克隆机制、序列化机制、多线程机制、反射机制以及垃圾回收机制和异常处理机制。在这篇文章中,我们将深入探讨前三个机制。 首先,克隆机制允许我们在内存中复制...

    JAVA创建对象的四种方法

    -java 创建对象的四种方法是指在 Java 中创建对象的不同方式,它们分别是使用 new 语句创建对象、使用反射机制创建对象、使用 clone() 方法创建对象和使用反序列化机制创建对象。 - 使用 new 语句创建对象是 Java ...

    (完整word版)java6个机制.doc

    Java 语言中的六个核心机制包括克隆、序列化、多线程、异常处理、垃圾回收以及反射。在这里,我们将详细探讨前三个机制。 首先,让我们来看看克隆机制。克隆在编程中指的是复制一个对象并在内存中创建其副本。在 ...

Global site tag (gtag.js) - Google Analytics