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 的克隆或副本。
2,什么时候使用Clone?
当需要修改对象属性,又不想影响原来的属性值,这时候就应该使用clone了。
3, 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对象。
4. Clone()方法的使用 Clone()方法的使用比较简单,注意如下几点即可: a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
万类之初的 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() :
4,shallow clone and deep clone
Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。Java Collection 类库中具体数据结构类( ArrayList/LinkedList , HashSet/TreeSet , HashMap/TreeMap 等)都具有克隆功能,且都是 Shallow Clone。在有种情况下,这种shallow Clone就会问题,这个情况就是当,要clone的对象中的某个属性是一个引用, 这样克隆类就和原始类共享了一部分信息,对这个属性操作就会影响原始类,所以就需要deep clone.
deep clone的简单例子:
Java代码
public class TestClone {
/**
* @param args
*/
public static void main(String[] args) {
try {
new TestClone().cloneObject();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void cloneObject() throws CloneNotSupportedException {
Person p = new Person();
Man man = new Man();
man.setSalory("111123");
p.setName("zhangfei");
p.setMan(man);
//man.setSalory("122335");//(1)
Person pp = p.getClonePerson(p);
man.setSalory("122335");//(2)
pp.setName("aa");
System.out.println("pp.getName()= " + pp.getName() + " pp.man.getSalory()= "+pp.getMan().getSalory());
System.out.println("p.getName()=" + p.getName()+" p.man.getSalory()= "+p.getMan().getSalory());
}
}
class Person implements Cloneable {
private String name = "";
private Man man;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getClonePerson(Person p) throws CloneNotSupportedException {
Person pp = (Person) p.clone();
return pp;
}
public Man getMan() {
return man;
}
public void setMan(Man man) {
this.man = man;
}
public Object clone() throws CloneNotSupportedException{
Person p = (Person) super.clone();
p.man = this.getMan().getCloneMan(this.getMan());
return p;
}
}
class Man implements Cloneable{
private String salory = "";
public String getSalory() {
return salory;
}
public void setSalory(String salory) {
this.salory = salory;
}
public Man getCloneMan(Man man) throws CloneNotSupportedException{
Man ma = (Man)man.clone();
return ma;
}
}
简单地说, 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 的克隆或副本。
2,什么时候使用Clone?
当需要修改对象属性,又不想影响原来的属性值,这时候就应该使用clone了。
3, 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对象。
4. Clone()方法的使用 Clone()方法的使用比较简单,注意如下几点即可: a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
万类之初的 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() :
4,shallow clone and deep clone
Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。Java Collection 类库中具体数据结构类( ArrayList/LinkedList , HashSet/TreeSet , HashMap/TreeMap 等)都具有克隆功能,且都是 Shallow Clone。在有种情况下,这种shallow Clone就会问题,这个情况就是当,要clone的对象中的某个属性是一个引用, 这样克隆类就和原始类共享了一部分信息,对这个属性操作就会影响原始类,所以就需要deep clone.
deep clone的简单例子:
Java代码
public class TestClone {
/**
* @param args
*/
public static void main(String[] args) {
try {
new TestClone().cloneObject();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void cloneObject() throws CloneNotSupportedException {
Person p = new Person();
Man man = new Man();
man.setSalory("111123");
p.setName("zhangfei");
p.setMan(man);
//man.setSalory("122335");//(1)
Person pp = p.getClonePerson(p);
man.setSalory("122335");//(2)
pp.setName("aa");
System.out.println("pp.getName()= " + pp.getName() + " pp.man.getSalory()= "+pp.getMan().getSalory());
System.out.println("p.getName()=" + p.getName()+" p.man.getSalory()= "+p.getMan().getSalory());
}
}
class Person implements Cloneable {
private String name = "";
private Man man;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getClonePerson(Person p) throws CloneNotSupportedException {
Person pp = (Person) p.clone();
return pp;
}
public Man getMan() {
return man;
}
public void setMan(Man man) {
this.man = man;
}
public Object clone() throws CloneNotSupportedException{
Person p = (Person) super.clone();
p.man = this.getMan().getCloneMan(this.getMan());
return p;
}
}
class Man implements Cloneable{
private String salory = "";
public String getSalory() {
return salory;
}
public void setSalory(String salory) {
this.salory = salory;
}
public Man getCloneMan(Man man) throws CloneNotSupportedException{
Man ma = (Man)man.clone();
return ma;
}
}
发表评论
-
深入分析 Java 中的中文编码问题
2011-11-16 07:45 0几种常见的编码格式 ... -
Java 编码
2011-11-16 07:44 0http://zhidao.baidu.com/quest ... -
java字符编码原理解析
2011-11-16 07:43 0可以理解为计算机没 ... -
HttpClient
2011-11-03 11:07 824From http://www.blogjava.net/Al ... -
ECLIPSE ANT OutOfMemoryError
2011-08-04 17:23 1011ANT BUILD MEMORY ERROR: [cl ... -
JDBC BATCH
2011-07-05 14:58 0PreparedStatement ps = conn.pre ... -
OUT OF MEMORY WHEN BUILD
2011-02-22 17:47 01, ANT BUILD: In Eclipse op ... -
spring weblogic jndi
2011-02-16 09:18 1837weblogic:weblogic8.1 数据库:MySql ... -
log4j 邮件
2011-01-24 15:54 0<!-- 设置上下文参数 --> ... -
tomcat weblogic
2010-12-01 11:25 1862EJB 层基本搞定,以前测试 EJB 也都是写一个 appli ... -
ant weblogic “local class incompatible: stream classdesc serialVersionUI”
2010-11-29 12:41 2227weblogic.management.Management ... -
Debugging with the Maven Jetty Plugin in Eclipse
2010-11-15 17:42 1035debug: http://docs.codehaus.or ... -
maven tomcat eclipse debug
2010-11-15 17:36 1946from: http://bandaidprogrammin ... -
maven app tomcat 部署
2010-11-11 15:56 1307修改pom.xml,添加如下配置: <build ... -
Maven Cargo Tomcat 部署
2010-11-11 15:49 1769pom.xml中<build>下添加如下代码: ... -
java中读取配置文件各种方法
2010-09-07 12:31 01。使用Java.util.Properties类的load( ... -
ThreadGroup
2010-05-25 08:47 0在Java中每个线程都属于某个线程组(ThreadGroup) ... -
java Excel 导出
2010-03-28 20:06 0public void createExcel(OutputS ... -
java小数保留两位小数
2009-11-19 16:49 2337方式一: 四舍五入 double f = ... -
java中实现xml schema 验证文件
2009-11-16 20:05 3877XML 是可扩展标记语言,也就是说其中的标记我们可以按照我们 ...
相关推荐
java克隆技术的入门及深入研究,帮助读者更好的理解java克隆技术,掌握关键知识点。
java的两种深度克隆方法,1cloneTest是用Cloneable接口的clone方法实现(对象必须要实现cloneable接口).2cloneSerialize.java是用对象流写对象到byte数组中,然后从byte数组中取得对象.(对象必须要实现serializble接口)
可以更好的去理解java克隆的运用,尤其在多线程的运用过程中,多个对象进行操作过程中,可以先进行对 对象进行 备份,首先就克隆一份,当多线程对对象操作过程中,与异常情况,可以对对象进行恢复,克隆还其他的用途,学会...
现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在java中也有这么一个概念,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的...
乒乓这是 Pong 的一个非常简单的 Java 克隆,我将它作为一个项目来应用我在 Java 图形编程中学到的东西。 这是众多尝试中的一个,因为我大部分时间都在不知道自己在做什么(自从我最初创建这个克隆以来已经进行了...
在Java编程语言中,克隆是一种创建对象副本的方法,它允许我们复制一个对象并拥有一个完全独立的新实例,而不是仅仅引用原始对象。克隆技术在处理复杂数据结构、避免对象共享以及实现对象复制等方面有着广泛的应用。...
在Java编程语言中,克隆和序列化是两个重要的概念,它们在数据处理和对象管理中扮演着关键角色。下面将分别对这两个概念进行详细解释,并结合实例和源代码进行阐述。 **一、克隆** 1. **克隆定义**:克隆是指创建...
Java 深克隆与浅克隆 Java 中的克隆机制可以让我们方便地制造出一个对象的副本来,但是在克隆过程中需要注意浅克隆和深克隆的区别。 浅克隆(Shallow Clone)是指对对象的域进行简单的 copy,对象的reference变量...
克隆/重制/补丁。 本软件按“原样”分发,不提供任何类型的明示或暗示的保证或条件。 使用原始 EFS 数据文件并需要安装 EFS 1.4。 应该适用于所有模组。 (可能比本文档更易于导航。) 如果您有一个适用于 EFS 但不...
在Java编程语言中,克隆是一种创建对象副本的方法,它允许我们复制一个对象并得到一个与原对象相同但独立的新对象。克隆分为两种主要类型:深克隆和浅克隆。理解这两种克隆的区别是Java面向对象编程中的重要概念。 ...
在Java编程语言中,"深度克隆"是一个重要的概念,主要涉及到对象复制。深度克隆,也称为完全克隆,是指创建一个与原对象相同的新对象,不仅复制原对象的所有属性,还复制了原对象中引用的对象。这通常用于创建一个...
### Java深度克隆知识点详解 #### 一、深度克隆概念 在Java中,深度克隆是一种用于创建对象副本的方法,它可以确保复制出的新对象与原对象之间没有任何引用关系,也就是说,新对象中的所有成员变量(包括引用类型)...
在Java编程语言中,克隆是创建一个对象副本的过程,这个副本与原对象有相同的属性值,但作为不同的对象存在。克隆分为两种主要类型:浅克隆(Shallow Clone)和深克隆(Deep Clone)。这篇博客文章将探讨这两种克隆...
Java中的对象复制与克隆是程序开发中常见的需求,主要用于创建一个对象的副本,而不会影响原始对象的状态。这里主要讨论两种类型的对象拷贝:浅拷贝和深拷贝。 浅拷贝,也称为表面拷贝,是创建一个新的对象,然后将...
Java中的克隆是一种复制对象的方式,它允许创建一个与原对象具有相同属性的新对象。在Java中,克隆是通过`Object`类的`clone()`方法实现的,但使用克隆时有一些特定的要求和限制。 首先,为了能够克隆一个对象,该...
城堡游戏“ Wesnoth之战”的Java克隆单位可以移动一定数量的步骤。 有不同类型的单位,每个单位都有自己的攻击和防御等级。 玩家只能在视线范围内看到敌方单位。 游戏功能包括:随机生成的游戏场,战争迷雾和战斗...