原帖: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 。
相关推荐
现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在java中也有这么一个概念,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的...
Java克隆(Clone)是Java语言的特性之一,本篇文章主要介绍了Java中的Clone机制是如何工作的,需要的朋友可以参考下
现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在java中也有这么一个概念,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的...
1 JAVA认识 2 JAVA数据类型 3 面向对象程序设计 4 JAVA集合 5 JAVA反射机制 6 JAVA注解(ANNOTATION) 7 JAVA中的异常类 ...20 JAVA克隆CLONE(复制) 21 JAVA 网络编程 22 JAVA 其他未归类 23 JNI概述
3. Java中垃圾回收的机制是什么? 4. Java中什么是反射? 5. Java中什么是线程安全? 6. Java中抽象类和接口的区别是什么? 7. Java中什么是异常? 8. Java中如何防止对象的clone? 9. Java中什么是泛型? 10. Java...
Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...
Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...
clone.docx Date日期.docx GC垃圾回收机制.docx instanceof运算符.docx io.docx java基础关键字.docx java命名和数据类型.docx java序列化.docx Math类.docx Object(对象).docx operator(运算符).docx ...
46、java 中实现多态的机制是什么? 12 47、在java 中一个类被声明为final 类型,表示了什么意思? 12 48、下面哪些类可以被继承? 12 49、指出下面程序的运行结果: 【基础】 13 52、关于内部类: 13 53、数据类型...
43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...
43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...
23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested ...
43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...
一. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。...43、Java中的异常处理机制的简单原理和应用。 28 等等........
Java中有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode、equals、clone、toString、getClass等。其中getClass返回一个Class 对象。Class对象十分特殊。他是...
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...
rollbackSegmentInfos = (SegmentInfos) segmentInfos.clone(); // 克隆 } // 默认的删除策略实现类为KeepOnlyLastCommitDeletionPolicy,它只是保证将最近提交删除的索引文件,提交删除动作 // ...
43、Java中的异常处理机制的简单原理和应用。 28 44、请写出你最常见到的5个runtime exception。 28 45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出...