原文地址 http://hi.baidu.com/limp_t/blog/item/83bdb2ad2025f60d4a36d67d.html
--------------------------------------------------------------------------------
经常听到有人说java中没有指针。事实如此吗?no,java是有指针的,只不过换了个名字而已,也就是我们经常提到的引用。我们知道,在java中一切都是对象,那么我们如何操控对象?如何在成千上万的对象中找到我们所需的那个对象呢?又是如何让对象按照我们的意思来完成任务的呢?
Object o = new Object();
这是java中最常见的语句了,在这句话中做了三件事。首先声明一个Object类型的变量o,在内存中为对象划分一块地址new Object(),将声明的变量指向内存中的对象。如此一来,我们就可以通过o来操纵对象了。就好像孩子们玩的遥控飞机,在空中飞行的是飞机,而使它做出 优美动作的却是孩子们手中的摇控器。
"克隆"是如今听到的较多的词汇,听说已经将某只羊克隆了好几份了。但愿这种技术不要在人身上实验。java中也有"克隆",与现实世界的克隆一样,将一个实际存在的对象拷贝几份。如下:
//倒霉的羊
public class Sheep implements Cloneable...{
private String name;
public void setName(String arg) ...{
name = arg;
}
public String getName()...{
return name;
}
public Object clone() throws CloneNotSupportedException ......{
return super.clone();
}
}
//克隆
public class Main ...{
public static void main(String[] args) throws CloneNotSupportedException...{
Sheep sheep = new Sheep(); //先得到那只羊的实例
sheep.setName("我是真的"); //给它做个记号
System.out.println("sheep.getName() = " + sheep.getName());
Sheep sheepClone = (Sheep)sheep.clone(); //开始克隆
System.out.println("sheepClone.getName() = " + sheepClone.getName());
}
} 运行程序结果为:
sheep.getName() = 我是真的
sheepClone.getName() = 我是真的
两只羊是一模一样的(哪怕那只羊瘸腿)。让我们来看看代码。首先要注意的是Sheep类实现了Cloneable接口(该接口属于java.lang包, 默认已经导入了),该接口中并没有定义要实现的方法,是个空接口,起标志作用。也就是说,实现了这个接口的羊就不再是只普通的羊,它是一只可以被克隆的 羊。再往下看,有个clone方法,返回Object类型的对象,并抛出CloneNotSupportedException异常。该方法覆写了父类 (Object)的clone方法,并在最后调用了super.clone(),这也意味着无论clone类继承结构是什么样的,super.clone ()都会直接或间接调用Object类的clone()方法。看看jdk帮助文档会发现,Object类的clone()是一个native方法,我们知 道,native方法的效率一般来说都是远高于java中的非native方法。这也说明了new一个对象,然后将原对象中的数据导入到新创建的对象中去 的做法是多么愚蠢。必须说明的是Object中的clone方法是protected的,所以要使用clone就必须继承Object类(默认)。并且为 了可以使其它类调用该方法,必须将其作用域设置为public.
以上只是一个简单clone的实现。明天说说"影子clone"和"深度clone".
夜,深了。何为影子clone?先看一下例子。
在
//倒霉的羊
public class Sheep implements Cloneable...{
private String name;
public void setName(String arg) ...{
name = arg;
}
public String getName() ...{
return name;
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
//羊圈
public class Sheepfold implements Cloneable ...{
public Sheep sheep;
public String name;
public Sheepfold() ...{
sheep = new Sheep();
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
//克隆
public class Main ...{
public static void main(String[] args) throws Exception ...{
Sheepfold fold = new Sheepfold();
fold.name = "小羊圈";
fold.sheep.setName("小羊");
Sheepfold fold2 = (Sheepfold)fold.clone();
System.out.println(" fold2.name = " + fold2.name);
System.out.println(" fold2.sheep.getName() = " + fold2.sheep.getName());
fold2.name = "大羊圈";
fold2.sheep.setName("大羊");
System.out.println("=====================================");
System.out.println(" fold2.name = " + fold2.name);
System.out.println("* fold2.sheep.getName() = " + fold2.sheep.getName());
System.out.println(" fold.name = " + fold.name);
System.out.println("* fold.sheep.getName() = " + fold.sheep.getName());
System.out.println("=====================================");
}
}这个例子中有三个类,Sheep和Sheepflod都实现了Cloneable接口,并且覆写了Object类的clone方法,说明这两个类是具 有克隆能力的。注意一点,在Sheepflod中持有一个Sheep的实例,并在Main类中对其进行克隆,结果如下:
fold2.name = 小羊圈
fold2.sheep.getName() = 小羊
=====================================
fold2.name = 大羊圈
* fold2.sheep.getName() = 大羊
fold.name = 小羊圈
* fold.sheep.getName() = 大羊
=====================================
请注意一下结果中带有"*"号的两条结果语句。fold2.sheep和fold.sheep的name都变为了"大羊 ",很奇怪是吗?在此之前,我们只对fold2.sheep的name赋过值。为什么fold.sheep的name也变为了"大羊"呢?原因很简单,因 为它们是指向同一个对象的不同引用。从中可以看出,调用Object类中clone()方法时,首先在内存中划分一块同原对象相同的空间,然后将原对象的 内容原样拷贝至新对象。我们知道,java中有基本数据类型,对于基本数据类型,这样的操作是没有问题的,但对非基本类型变量,它们保存的仅仅是对象的引 用,这也是为什么clone后非基本类型变量和原对象中的变量指向同一个对象的原因。可能你已经注意到,程序中用到了String类型,即对象,为什么没 有出现引用指向同一地址的情况?这是因为String是一个不可更改的类(immutable class),每次给它赋值时,都会产生一个新的String对象。如 String str = "a"; str += "b";在这两句代码中,当执行str += "b"时,实际上是重新成生了一个值为"ab"的 String对象,即重新分配了一块内存空间。以上clone方法通常被称为"影子clone"."影子clone"给我们留下了一个问题,即多个引用指 向同一个对象。如何解决该问题呢?答案为"深度clone".把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为 如下即可:很简单,只需将Sheepfold的clone()方法改为如下即可:
(R q9N Y&W S#T0
public Object clone() throws CloneNotSupportedException {
Sheepfold fold = (Sheepfold)super.clone();
sheep = (Sheep)fold.sheep.clone();
return fold;
}
Clone基本知识储备
在Java里提到clone技术,就不能不提 java.lang.Cloneable接口和含有clone方法的Object类。所有具有clone功能的类都有一个特性,那就是它直接或间接地实现 了Cloneable接口。否则,我们在尝试调用clone()方法时,将会触发CloneNotSupportedException异常。下面我们通 过对Object类的部分源码的分析,来发现和理解这一特性。请看JDK中Object# clone()方法的源码:
/* ………… * @return a clone of this instance. * @exception? CloneNotSupportedException? if the object''s class does not *support the Cloneable interface. Subclasses *that override the clone method can also * throw this exception to indicate that an instance cannot *be cloned. * @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException;
这段源码的@exception部分的描述内容证实了上文关于clone对象特性论断的正确 性。它明确指出对象类必须支持Cloneable接口,否则即使派生类覆盖了Object#clone()方法,也同样会抛出 CloneNotSupportedException这个异常。关于覆盖clone()方法,后续文章将会用专门篇幅进行比较详细的分析.
一、clone的实现
1.实现Cloneable接口
通过上一篇的介绍,我们知道,一个类若要具备clone功能,就必须实现 Cloneable接口。做到这一步,clone功能已经基本实现了。Clone功能对我们来说,最主要的还是要能够使用它。那么我们如何才能使用 clone功能呢?答案是覆盖Object#clone()方法。
2. 覆盖Object#clone()方法
为什么需要覆盖Object#clone()方法?这里得再次从jdk源码说起。JDK中Object# clone()方法的原型是:
protected native Object clone() throws CloneNotSupportedException;
是否注意到,这里clone()方法修饰符是protected,而不是 public。这种访问的不可见性使得我们对Object#clone()方法不可见。相信读者已明白为什么要覆盖Object#clone()方法。而 且,覆盖的方法的修饰符必须是public,如果还保留为protected,覆盖将变得没有实际意义。下面举一个具有clone功能的简单的例子:
/* * 具有clone功能的类的例子 */ public class CloneableObjExample implements Cloneable { //……部分代码已省略…… private String name = null; private int score = 0; /** * NOTE: 将protected 修饰符 更改为 public * @see java.lang.Object#clone() */ public/*protected*/ Object clone() throws CloneNotSupportedException { // call父类的clone方法 Object result = super.clone(); //TODO: 定制clone数据 return result; } }
3.定制clone
至此,clone已经真相大白。Clone的对象我们可以对其进行定制。还就上面的例子来说。下面的方法对功能做了一定的增强:
public/*protected*/ Object clone() throws CloneNotSupportedException { // call父类的clone方法 CloneableObjExample result = (CloneableObjExample)super.clone(); //TODO: 定制clone数据 //虽然”clone”了,但还可以做点调整 result.name = “New Name”; result.score = 90; return result; }
Clone通常有两种类型即浅clone和深clone。首先,分析一下两种的不同。浅 clone和深clone都是clone,它们本质区别是对象内部的成员属性(非原生类型属性,如int等)在clone时是否处理为引用。如果仍然保留 为引用,则称为浅clone,反之称为深clone。其实这两个概念也是相对的概念。在处理上它们有点区别,浅clone方式得到clone对象即可,深 clone方式在得到clone对象后,还需要对引用的成员属性进行“clone”处理。从这个层次上说,深clone并没有什么特别地困难,简单讲就是 创建好对象,再设置一些成员属性。关于深clone,网上的文章已经有太多,有点目不暇接的感觉,本文不再赘述,这也不是本文的重点。
实现方案为采用java reflection技术和递归相结合。
大致步骤描述如下:首先采用java reflection技术动态获取成员方法列表。然后视clone的深度,对具备clone条件的并且有必要clone的成员进行逐一clone。这是一 个递归的过程,直到clolne深度已到为止或者到对象已经没有需要clone的成员属性为止。
何为具备clone条件的并且有必要clone的成员进行逐一clone?比 如,原生类型(primitive type),定为瞬态(Transient)的类型,不可访问的类型(!Field#isAccessible()),没实现Cloneable接口的类 型等等,都不具备clone条件。String等java定义的类型就不需要再深入clone了,这些属于没必要进行clone的情况。但List类型等 “容器”类是有必要clone的成员类型。
据此,递归程序示意如下(deepClone为java 方法):
/** * @return Object 返回clone的对象 * @param obj 原对象 * @param length clone的深度 */ public Object deepClone(Object obj, int length) { Object result = obj; //此处为伪代码: 如果对象obj不具备clone条件,就返回result,这也是递归的结束条件。 //此处为伪代码: 如果对象obj没必要clone,就返回result /***此处为伪代码:开始进行“clone”对象。这地方是调一个抽象方法来处理,*这样可以增加很多灵活性。该方法主要目的是实现“clone”对象方案。注意:*这里面的“clone”方案可能是我们想都想不到的方案,它可能有很多创意,*但效果都是一样的,就是要“clone”个新的对象出来。当然最容易想的就*是Object#clone()方法了。示意如下:*/ result = om.clone(obj); /***此处为伪代码: 获取具备clone条件的并且有必要clone的所有成员。这地方*也是调一个抽象方法来处理。同样是为了增强灵活性。获取这些成员的方法*有很多,可能是通过setter和getter对来得到,也可能是通过get fields *等等方法得到(这种方法可能不少成员是无法直接访问的,往往需要结合别*的方法),甚至是多种方法的综合。总之,目的只有一个,就是获得这些成员。*/for (int i = 0; i < fields.length; i++) { //对成员进行处理 //如果已不需要再判断成员了,那除了“容器”成员外,已经clone结束 if (length <= 1) { if (!“容器”成员) { continue; } try { //只需clone一次了,注意递归方法的深度参数传入1clonedFieldValue = deepClone(“容器”成员的值, 1); } catch (Exception ex2) { ex2.printStackTrace(); return result; } } else { try { clonedFieldValue = deepClone(成员的值, length - 1); } catch (Exception ex) { ex.printStackTrace(); return result; } } try { //此处为伪代码:将clone好的值(clonedFieldValue)设进去 } catch (Exception ex) { ex.printStackTrace(); return result; } }//for.. return result; }
至此,已完成了“N深clone”。下面讨论一下别的相关问题。比如说这种深度clone原 本是A-->B-->C--……-->xz这样一种情况,就是说A类含有B成员,B里面又含有C成员,依此类推。如果想在“N深 clone”时,只clone“xz”这个成员怎么办?其实很简单,这个问题主要是要解决在递归过程中有些成员需要clone同时有些成员不需clone 仍保留引用这个问题。在上面的递归示例中已经提到,实现“clone”的“方案”已经被定义成抽象方法,那么我们只要对这个方法做一个满足这个需求的实现 即可。
--------------------------------------------------------------------------------
经常听到有人说java中没有指针。事实如此吗?no,java是有指针的,只不过换了个名字而已,也就是我们经常提到的引用。我们知道,在java中一切都是对象,那么我们如何操控对象?如何在成千上万的对象中找到我们所需的那个对象呢?又是如何让对象按照我们的意思来完成任务的呢?
Object o = new Object();
这是java中最常见的语句了,在这句话中做了三件事。首先声明一个Object类型的变量o,在内存中为对象划分一块地址new Object(),将声明的变量指向内存中的对象。如此一来,我们就可以通过o来操纵对象了。就好像孩子们玩的遥控飞机,在空中飞行的是飞机,而使它做出 优美动作的却是孩子们手中的摇控器。
"克隆"是如今听到的较多的词汇,听说已经将某只羊克隆了好几份了。但愿这种技术不要在人身上实验。java中也有"克隆",与现实世界的克隆一样,将一个实际存在的对象拷贝几份。如下:
//倒霉的羊
public class Sheep implements Cloneable...{
private String name;
public void setName(String arg) ...{
name = arg;
}
public String getName()...{
return name;
}
public Object clone() throws CloneNotSupportedException ......{
return super.clone();
}
}
//克隆
public class Main ...{
public static void main(String[] args) throws CloneNotSupportedException...{
Sheep sheep = new Sheep(); //先得到那只羊的实例
sheep.setName("我是真的"); //给它做个记号
System.out.println("sheep.getName() = " + sheep.getName());
Sheep sheepClone = (Sheep)sheep.clone(); //开始克隆
System.out.println("sheepClone.getName() = " + sheepClone.getName());
}
} 运行程序结果为:
sheep.getName() = 我是真的
sheepClone.getName() = 我是真的
两只羊是一模一样的(哪怕那只羊瘸腿)。让我们来看看代码。首先要注意的是Sheep类实现了Cloneable接口(该接口属于java.lang包, 默认已经导入了),该接口中并没有定义要实现的方法,是个空接口,起标志作用。也就是说,实现了这个接口的羊就不再是只普通的羊,它是一只可以被克隆的 羊。再往下看,有个clone方法,返回Object类型的对象,并抛出CloneNotSupportedException异常。该方法覆写了父类 (Object)的clone方法,并在最后调用了super.clone(),这也意味着无论clone类继承结构是什么样的,super.clone ()都会直接或间接调用Object类的clone()方法。看看jdk帮助文档会发现,Object类的clone()是一个native方法,我们知 道,native方法的效率一般来说都是远高于java中的非native方法。这也说明了new一个对象,然后将原对象中的数据导入到新创建的对象中去 的做法是多么愚蠢。必须说明的是Object中的clone方法是protected的,所以要使用clone就必须继承Object类(默认)。并且为 了可以使其它类调用该方法,必须将其作用域设置为public.
以上只是一个简单clone的实现。明天说说"影子clone"和"深度clone".
夜,深了。何为影子clone?先看一下例子。
在
//倒霉的羊
public class Sheep implements Cloneable...{
private String name;
public void setName(String arg) ...{
name = arg;
}
public String getName() ...{
return name;
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
//羊圈
public class Sheepfold implements Cloneable ...{
public Sheep sheep;
public String name;
public Sheepfold() ...{
sheep = new Sheep();
}
public Object clone() throws CloneNotSupportedException ...{
return super.clone();
}
}
//克隆
public class Main ...{
public static void main(String[] args) throws Exception ...{
Sheepfold fold = new Sheepfold();
fold.name = "小羊圈";
fold.sheep.setName("小羊");
Sheepfold fold2 = (Sheepfold)fold.clone();
System.out.println(" fold2.name = " + fold2.name);
System.out.println(" fold2.sheep.getName() = " + fold2.sheep.getName());
fold2.name = "大羊圈";
fold2.sheep.setName("大羊");
System.out.println("=====================================");
System.out.println(" fold2.name = " + fold2.name);
System.out.println("* fold2.sheep.getName() = " + fold2.sheep.getName());
System.out.println(" fold.name = " + fold.name);
System.out.println("* fold.sheep.getName() = " + fold.sheep.getName());
System.out.println("=====================================");
}
}这个例子中有三个类,Sheep和Sheepflod都实现了Cloneable接口,并且覆写了Object类的clone方法,说明这两个类是具 有克隆能力的。注意一点,在Sheepflod中持有一个Sheep的实例,并在Main类中对其进行克隆,结果如下:
fold2.name = 小羊圈
fold2.sheep.getName() = 小羊
=====================================
fold2.name = 大羊圈
* fold2.sheep.getName() = 大羊
fold.name = 小羊圈
* fold.sheep.getName() = 大羊
=====================================
请注意一下结果中带有"*"号的两条结果语句。fold2.sheep和fold.sheep的name都变为了"大羊 ",很奇怪是吗?在此之前,我们只对fold2.sheep的name赋过值。为什么fold.sheep的name也变为了"大羊"呢?原因很简单,因 为它们是指向同一个对象的不同引用。从中可以看出,调用Object类中clone()方法时,首先在内存中划分一块同原对象相同的空间,然后将原对象的 内容原样拷贝至新对象。我们知道,java中有基本数据类型,对于基本数据类型,这样的操作是没有问题的,但对非基本类型变量,它们保存的仅仅是对象的引 用,这也是为什么clone后非基本类型变量和原对象中的变量指向同一个对象的原因。可能你已经注意到,程序中用到了String类型,即对象,为什么没 有出现引用指向同一地址的情况?这是因为String是一个不可更改的类(immutable class),每次给它赋值时,都会产生一个新的String对象。如 String str = "a"; str += "b";在这两句代码中,当执行str += "b"时,实际上是重新成生了一个值为"ab"的 String对象,即重新分配了一块内存空间。以上clone方法通常被称为"影子clone"."影子clone"给我们留下了一个问题,即多个引用指 向同一个对象。如何解决该问题呢?答案为"深度clone".把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为 如下即可:很简单,只需将Sheepfold的clone()方法改为如下即可:
(R q9N Y&W S#T0
public Object clone() throws CloneNotSupportedException {
Sheepfold fold = (Sheepfold)super.clone();
sheep = (Sheep)fold.sheep.clone();
return fold;
}
Clone基本知识储备
在Java里提到clone技术,就不能不提 java.lang.Cloneable接口和含有clone方法的Object类。所有具有clone功能的类都有一个特性,那就是它直接或间接地实现 了Cloneable接口。否则,我们在尝试调用clone()方法时,将会触发CloneNotSupportedException异常。下面我们通 过对Object类的部分源码的分析,来发现和理解这一特性。请看JDK中Object# clone()方法的源码:
/* ………… * @return a clone of this instance. * @exception? CloneNotSupportedException? if the object''s class does not *support the Cloneable interface. Subclasses *that override the clone method can also * throw this exception to indicate that an instance cannot *be cloned. * @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException;
这段源码的@exception部分的描述内容证实了上文关于clone对象特性论断的正确 性。它明确指出对象类必须支持Cloneable接口,否则即使派生类覆盖了Object#clone()方法,也同样会抛出 CloneNotSupportedException这个异常。关于覆盖clone()方法,后续文章将会用专门篇幅进行比较详细的分析.
一、clone的实现
1.实现Cloneable接口
通过上一篇的介绍,我们知道,一个类若要具备clone功能,就必须实现 Cloneable接口。做到这一步,clone功能已经基本实现了。Clone功能对我们来说,最主要的还是要能够使用它。那么我们如何才能使用 clone功能呢?答案是覆盖Object#clone()方法。
2. 覆盖Object#clone()方法
为什么需要覆盖Object#clone()方法?这里得再次从jdk源码说起。JDK中Object# clone()方法的原型是:
protected native Object clone() throws CloneNotSupportedException;
是否注意到,这里clone()方法修饰符是protected,而不是 public。这种访问的不可见性使得我们对Object#clone()方法不可见。相信读者已明白为什么要覆盖Object#clone()方法。而 且,覆盖的方法的修饰符必须是public,如果还保留为protected,覆盖将变得没有实际意义。下面举一个具有clone功能的简单的例子:
/* * 具有clone功能的类的例子 */ public class CloneableObjExample implements Cloneable { //……部分代码已省略…… private String name = null; private int score = 0; /** * NOTE: 将protected 修饰符 更改为 public * @see java.lang.Object#clone() */ public/*protected*/ Object clone() throws CloneNotSupportedException { // call父类的clone方法 Object result = super.clone(); //TODO: 定制clone数据 return result; } }
3.定制clone
至此,clone已经真相大白。Clone的对象我们可以对其进行定制。还就上面的例子来说。下面的方法对功能做了一定的增强:
public/*protected*/ Object clone() throws CloneNotSupportedException { // call父类的clone方法 CloneableObjExample result = (CloneableObjExample)super.clone(); //TODO: 定制clone数据 //虽然”clone”了,但还可以做点调整 result.name = “New Name”; result.score = 90; return result; }
Clone通常有两种类型即浅clone和深clone。首先,分析一下两种的不同。浅 clone和深clone都是clone,它们本质区别是对象内部的成员属性(非原生类型属性,如int等)在clone时是否处理为引用。如果仍然保留 为引用,则称为浅clone,反之称为深clone。其实这两个概念也是相对的概念。在处理上它们有点区别,浅clone方式得到clone对象即可,深 clone方式在得到clone对象后,还需要对引用的成员属性进行“clone”处理。从这个层次上说,深clone并没有什么特别地困难,简单讲就是 创建好对象,再设置一些成员属性。关于深clone,网上的文章已经有太多,有点目不暇接的感觉,本文不再赘述,这也不是本文的重点。
实现方案为采用java reflection技术和递归相结合。
大致步骤描述如下:首先采用java reflection技术动态获取成员方法列表。然后视clone的深度,对具备clone条件的并且有必要clone的成员进行逐一clone。这是一 个递归的过程,直到clolne深度已到为止或者到对象已经没有需要clone的成员属性为止。
何为具备clone条件的并且有必要clone的成员进行逐一clone?比 如,原生类型(primitive type),定为瞬态(Transient)的类型,不可访问的类型(!Field#isAccessible()),没实现Cloneable接口的类 型等等,都不具备clone条件。String等java定义的类型就不需要再深入clone了,这些属于没必要进行clone的情况。但List类型等 “容器”类是有必要clone的成员类型。
据此,递归程序示意如下(deepClone为java 方法):
/** * @return Object 返回clone的对象 * @param obj 原对象 * @param length clone的深度 */ public Object deepClone(Object obj, int length) { Object result = obj; //此处为伪代码: 如果对象obj不具备clone条件,就返回result,这也是递归的结束条件。 //此处为伪代码: 如果对象obj没必要clone,就返回result /***此处为伪代码:开始进行“clone”对象。这地方是调一个抽象方法来处理,*这样可以增加很多灵活性。该方法主要目的是实现“clone”对象方案。注意:*这里面的“clone”方案可能是我们想都想不到的方案,它可能有很多创意,*但效果都是一样的,就是要“clone”个新的对象出来。当然最容易想的就*是Object#clone()方法了。示意如下:*/ result = om.clone(obj); /***此处为伪代码: 获取具备clone条件的并且有必要clone的所有成员。这地方*也是调一个抽象方法来处理。同样是为了增强灵活性。获取这些成员的方法*有很多,可能是通过setter和getter对来得到,也可能是通过get fields *等等方法得到(这种方法可能不少成员是无法直接访问的,往往需要结合别*的方法),甚至是多种方法的综合。总之,目的只有一个,就是获得这些成员。*/for (int i = 0; i < fields.length; i++) { //对成员进行处理 //如果已不需要再判断成员了,那除了“容器”成员外,已经clone结束 if (length <= 1) { if (!“容器”成员) { continue; } try { //只需clone一次了,注意递归方法的深度参数传入1clonedFieldValue = deepClone(“容器”成员的值, 1); } catch (Exception ex2) { ex2.printStackTrace(); return result; } } else { try { clonedFieldValue = deepClone(成员的值, length - 1); } catch (Exception ex) { ex.printStackTrace(); return result; } } try { //此处为伪代码:将clone好的值(clonedFieldValue)设进去 } catch (Exception ex) { ex.printStackTrace(); return result; } }//for.. return result; }
至此,已完成了“N深clone”。下面讨论一下别的相关问题。比如说这种深度clone原 本是A-->B-->C--……-->xz这样一种情况,就是说A类含有B成员,B里面又含有C成员,依此类推。如果想在“N深 clone”时,只clone“xz”这个成员怎么办?其实很简单,这个问题主要是要解决在递归过程中有些成员需要clone同时有些成员不需clone 仍保留引用这个问题。在上面的递归示例中已经提到,实现“clone”的“方案”已经被定义成抽象方法,那么我们只要对这个方法做一个满足这个需求的实现 即可。
相关推荐
在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在对象复制和克隆方面。这个小例子将帮助初学者理解如何在Java中使用`clone()`来创建对象的副本。让我们深入探讨`clone()`方法以及它在实际编程中的...
### Java中的`clone`方法详解:浅拷贝与深拷贝 #### 一、引言 在Java中,`clone`方法提供了一种快速复制对象的方式。它属于`Object`类的一部分,但需要显式地在子类中声明并实现`Cloneable`接口才能正常使用。本文...
详细的描述了Java中 clone方法使用
在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象克隆。本文将深入探讨Java中的`clone`方法,包括其工作原理、使用场景、注意事项以及一些个人实践心得。 首先,让我们理解什么是`clone`。...
Java中的clone方法详解_动力节点Java学院,动力节点口口相传的Java黄埔军校
Java中的`clone`方法是Java语言提供的一种复制对象的方式,它允许创建一个对象的副本,这个副本与原对象具有相同的属性值,但它们是两个独立的对象,修改副本不会影响原对象。`clone`方法存在于Java的`java.lang....
在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...
在Java编程语言中,`Clone`机制是一种对象复制的方式,允许创建一个现有对象的副本。在Java中,对象的默认复制是浅复制(shallow copy),这意味着只复制对象本身,而不复制它引用的对象。要实现深复制(deep copy)...
在Java编程语言中,克隆(Clone)机制是一种创建对象副本的方法,它允许开发者创建一个已有对象的新实例,这个新实例与原对象具有相同的属性值,但却是两个独立的对象,彼此的操作不会互相影响。克隆机制在某些情况...
clone的用法 希望有帮助,仅供参考 通过例子的分析,可以对克隆的方法有所深入了解
在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象的深拷贝与浅拷贝。本文将深入探讨Java中的`clone`方法及其相关知识点。 首先,`clone`方法是Java `Object`类的一个成员方法,定义为`...
Java中的`clone`方法是Java语言提供的一种复制对象的机制,它允许创建一个现有对象的副本,这个副本具有与原始对象相同的状态,但它们是独立的实体,对其中一个对象的修改不会影响另一个。`clone`方法是Java `Object...
Java中的对象克隆可以通过实现`Cloneable`接口并覆盖`clone()`方法来完成。对象的克隆分为浅拷贝和深拷贝两种形式。 **1. 浅拷贝** 浅拷贝是指创建一个新的对象,然后将原对象的所有非引用类型的成员变量复制到新...
Java Clone 深拷贝与浅拷贝的两种实现方法 Java Clone 是 Java 语言中的一种复制对象的机制,它可以将一个对象的所有属性和状态复制到另一个对象中,实现对象的深拷贝和浅拷贝。下面我们将讨论 Java 中的深拷贝和浅...
Java 中 clone() 的使用方法 Java 中的 clone() 方法是对象的复制方法,其主要作用是创建一个与原对象相同的新对象。下面将详细介绍 Java 中 clone() 方法的使用方法。 什么是 clone() 方法? clone() 方法是 ...
Java中的clone方法详解 在Java语言中,clone方法是一个非常重要的概念,它允许对象被复制,从而创造出一个新的对象。下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 ...
Java代码克隆,通常指的是在编程过程中,两个或多个代码段具有相似或完全相同的功能,这种现象被称为代码重复或代码克隆。在大型项目中,代码克隆可能会导致维护困难、增加bug出现的可能性以及降低代码的可读性和可...
在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在对象复制和克隆方面。这个方法来源于`java.lang.Object`类,所有Java类都默认继承了这个方法。本资料"Java中clone方法共6页.pdf.zip"可能包含了关于...
Java中的对象创建主要有两种方式,即使用`new`操作符创建新对象以及通过`clone`方法复制已有对象。本文将从JVM的角度深入探讨Java的`clone`操作,揭示其工作原理及其潜在的问题。 首先,让我们理解`clone`方法的...