当前位置:  技术问答>java相关

請教 : 如何複製一個對象 , clone() 不行, clone() 方法有甚麼作用?

    来源: 互联网  发布时间:2015-05-26

    本文导语:  Java 中,對象的付值 只是一個引用 , 例如 : Calendar date2 = date1 ,實際上 date1 ,date2 是同一個對象.  但是,我需要的是  date2 是 date1 的一個複製 . date1的變化不影响 date2 . 有甚麼方法呢 ? | ...

Java 中,對象的付值 只是一個引用 ,
例如 : Calendar date2 = date1 ,實際上 date1 ,date2 是同一個對象. 
但是,我需要的是  date2 是 date1 的一個複製 . date1的變化不影响 date2 .
有甚麼方法呢 ?

|
怎样应用clone()方法? 

一个很典型的调用clone()代码如下: 


class CloneClass implements Cloneable{ 
public int aInt; 
public Object clone(){ 
CloneClass o = null; 
try{ 
o = (CloneClass)super.clone(); 
}catch(CloneNotSupportedException e){ 
e.printStackTrace(); 

return o; 

} 




有三个值得注意的地方,一是希望能实现clone功能的CloneClass类实现了Cloneable接口,这个接口属于java.lang包,java.lang包已经被缺省的导入类中,所以不需要写成java.lang.Cloneable。另一个值得请注意的是重载了clone()方法。最后在clone()方法中调用了super.clone(),这也意味着无论clone类的继承结构是什么样的,super.clone()直接或间接调用了java.lang.Object类的clone()方法。下面再详细的解释一下这几点。 

应该说第三点是最重要的,仔细观察一下Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Object中clone()方法而不是先new一个类,然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。对于第二点,也要观察Object类中的clone()还是一个protected属性的方法。这也意味着如果要应用clone()方法,必须继承Object类,在Java中所有的类是缺省继承Object类的,也就不用关心这点了。然后重载clone()方法。还有一点要考虑的是为了让其它类能调用这个clone类的clone()方法,重载之后要把clone()方法的属性设置为public。 

那么clone类为什么还要实现Cloneable接口呢?稍微注意一下,Cloneable接口是不包含任何方法的!其实这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object的clone()方法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出CloneNotSupportedException异常。 

以上是clone的最基本的步骤,想要完成一个成功的clone,还要了解什么是"影子clone"和"深度clone"。 

什么是影子clone? 

下面的例子包含三个类UnCloneA,CloneB,CloneMain。CloneB类包含了一个UnCloneA的实例和一个int类型变量,并且重载clone()方法。CloneMain类初始化UnCloneA类的一个实例b1,然后调用clone()方法生成了一个b1的拷贝b2。最后考察一下b1和b2的输出: 


package clone; 
class UnCloneA { 
private int i; 
public UnCloneA(int ii) { i = ii; } 
public void doubleValue() { i *= 2; } 
public String toString() { 
return Integer.toString(i); 


class CloneB implements Cloneable{ 
public int aInt; 
public UnCloneA unCA = new UnCloneA(111); 
public Object clone(){ 
CloneB o = null; 
try{ 
o = (CloneB)super.clone(); 
}catch(CloneNotSupportedException e){ 
e.printStackTrace(); 

return o; 


public class CloneMain { 
public static void main(String[] a){ 
CloneB b1 = new CloneB(); 
b1.aInt = 11; 
System.out.println("before clone,b1.aInt = "+ b1.aInt); 
System.out.println("before clone,b1.unCA = "+ b1.unCA); 

CloneB b2 = (CloneB)b1.clone(); 
b2.aInt = 22; 
b2.unCA.doubleValue(); 
System.out.println("================================="); 
System.out.println("after clone,b1.aInt = "+ b1.aInt); 
System.out.println("after clone,b1.unCA = "+ b1.unCA); 
System.out.println("================================="); 
System.out.println("after clone,b2.aInt = "+ b2.aInt); 
System.out.println("after clone,b2.unCA = "+ b2.unCA); 




/** RUN RESULT: 
before clone,b1.aInt = 11 
before clone,b1.unCA = 111 
================================= 
after clone,b1.aInt = 11 
after clone,b1.unCA = 222 
================================= 
after clone,b2.aInt = 22 
after clone,b2.unCA = 222 
*/ 




输出的结果说明int类型的变量aInt和UnCloneA的实例对象unCA的clone结果不一致,int类型是真正的被clone了,因为改变了b2中的aInt变量,对b1的aInt没有产生影响,也就是说,b2.aInt与b1.aInt已经占据了不同的内存空间,b2.aInt是b1.aInt的一个真正拷贝。相反,对b2.unCA的改变同时改变了b1.unCA,很明显,b2.unCA和b1.unCA是仅仅指向同一个对象的不同引用!从中可以看出,调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。 

大多时候,这种clone的结果往往不是我们所希望的结果,这种clone也被称为"影子clone"。要想让b2.unCA指向与b2.unCA不同的对象,而且b2.unCA中还要包含b1.unCA中的信息作为初始信息,就要实现深度clone。

|
Calendar date2 = (Calendar) date1.clone();
需要作類型轉換 .

    
 
 

您可能感兴趣的文章:

  • java命名空间java.text类stringcharacteriterator的类成员方法: clone定义及介绍
  • 给自己的类提供Clone方法
  • java命名空间javax.swing.text类defaultstyleddocument.elementbuffer的类成员方法: clone定义及介绍
  • 请给我讲讲clone()方法究竟怎么复制对象,小妹谢谢大虾们了!
  • java命名空间java.text类decimalformatsymbols的类成员方法: clone定义及介绍
  • jquery的clone方法应用于textarea和select的bug修复
  • java命名空间java.text类dateformat的类成员方法: clone定义及介绍
  • jquery clone方法bug修复
  • java命名空间java.text类dateformatsymbols的类成员方法: clone定义及介绍
  • java命名空间java.util类locale的类成员方法: clone定义及介绍
  • java命名空间java.text类choiceformat的类成员方法: clone定义及介绍
  • java命名空间java.text类collator的类成员方法: clone定义及介绍
  • java命名空间java.text类numberformat的类成员方法: clone定义及介绍
  • java命名空间javax.swing.text类segment的类成员方法: clone定义及介绍
  • java命名空间java.text类rulebasedcollator的类成员方法: clone定义及介绍
  • java命名空间java.security.cert类pkixcertpathvalidatorresult的类成员方法: clone定义及介绍
  • java命名空间java.util.jar类manifest的类成员方法: clone定义及介绍
  • java命名空间java.text类decimalformat的类成员方法: clone定义及介绍
  • java命名空间java.util类calendar的类成员方法: clone定义及介绍
  • java命名空间java.text类format的类成员方法: clone定义及介绍
  • java命名空间java.text类messageformat的类成员方法: clone定义及介绍
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.net类httpcookie的类成员方法: clone定义及介绍
  • 在Java中什么是"Shallow clone"和"deep clone"?
  • java命名空间java.util类simpletimezone的类成员方法: clone定义及介绍
  • about the Object.clone() ??
  • java命名空间java.text接口characteriterator的类成员方法: clone定义及介绍
  • Linux下clone函数问题
  • java命名空间javax.management.modelmbean接口modelmbeaninfo的类成员方法: clone定义及介绍
  • 创建进程的系统调用clone()和fork()
  • java命名空间java.util类timezone的类成员方法: clone定义及介绍
  • 关于Clone的问题。
  • java命名空间javax.naming类compoundname的类成员方法: clone定义及介绍
  • 创建一个子进程,什么时候该用clone()而不是fork()?
  • java命名空间javax.swing类defaultlistselectionmodel的类成员方法: clone定义及介绍
  • clone()失败
  • java命名空间java.security.cert类collectioncertstoreparameters的类成员方法: clone定义及介绍
  • git只clone部分目录
  • java命名空间javax.swing.text类simpleattributeset的类成员方法: clone定义及介绍
  • 请教Clone问题!
  • java命名空间javax.management.relation类roleunresolved的类成员方法: clone定义及介绍
  • Vector包含的对象什么时候是可clone的?
  • java命名空间java.awt.image类imagefilter的类成员方法: clone定义及介绍
  • 谁用hg clone成功下载过solaris源码没??


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3