Java clone

本文详细解析了Java中Cloneable接口与Object类clone方法的使用,解释了为何调用super.clone()能得到当前类的副本,以及实现Cloneable接口的重要性。通过实例代码,深入探讨了clone方法的实现细节与保护权限机制。
 
class Employee implements Cloneable
{
   public Employee clone() throws CloneSupportedException
   {
      return (Employee)super.clone();
   }
}
/**
 * This (empty) interface must be implemented by all classes that wish to
 * support cloning. The implementation of {@code clone()} in {@code Object}
 * checks if the object being cloned implements this interface and throws
 * {@code CloneNotSupportedException} if it does not.
 * 
 * @see Object#clone
 * @see CloneNotSupportedException
 * @since Android 1.0
 */
public interface Cloneable {
    // Marker interface
}
/*
…………
     * @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;



 

 


1.为什么调用super.clone()方法能否经过转换后就能生成一个Employee的副本,它不是生成一个object的副本吗?

答:Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态得找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy【浅copy】的目的。 所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。

2.为什么要实现Cloneable接口?

指示Object.clone() 方法可以合法地对该类实例进行按字段复制

 

首先,Cloneable 这个接口仅做标识用,用于告诉调用者,“这个 class 是 cloneable 的”。

不过,如果你的 class 仅仅实现了这个接口,那是不够的。根据 JDK 文档,实现这个接口的同时,还要重写 clone() 方法。直接的理由很简单,如果不重写的话,Object.clone() 是 protected 的,不能被外部调用,重写时要改成 public 才可以。

至于“为什么要这样设计”,我想,可能是因为,实际使用 clone() 的场合大多数都需要的是“deep copy”,而 Object.clone() 实现的只是一个 field-to-field 的“shallow copy”,所以,要自己实现 clone() 方法对 Object reference 型的成员再进行 clone()。

再进一步,至于为什么 Object.clone() 不直接实现成“deep copy”,我想,可能是因为那样就太过分了,实际使用时并不一定都是完全的 deep copy,也许有些成员只要 shallow copy 就够了。所以,还是把具体实现的方法交给程序员决定。

 

 

1.Object中的clone执行的时候使用了RTTI(run-time  type  identification)的机制,动态得找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的。 
  所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。
2.这句话是J2SE API帮助里面的话,意思是要让实例调用clone方法就需要让此类实现Cloneable接口,API里面还有句话是:如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常,这便是“合法”的含义。 但请注意,Cloneable接口只是个标签接口,不含任何需要实现的方法,就像Serializable接口一样。
   
3. Object.clone()? 不能这么调用的。

回答还满意么。 



/*------------------以下是对问题的补充---悲哀的注释------------*/


ok 请容我慢慢道来
你看到clone()是Object的方法,而Object是所有类的父类,就认为可以用Object调用 clone是么?
但不能使用Object调用clone()方法
原因如下:
1.从你写法本身来看,Object.clone()肯定不行,因为Object是类, 而clone()是成员方法,所以不能用Object.clone();
2.那么是不是可以先Object obj=new Object();再obj.clone();或者Object.class.newInstance().clone()呢?还是不行。
  clone()对Object类对象本身是不可见的。所以你会发现找不到clone()方法
  原因是:clone()方法是protected访问权限
  方法原型:protected native java.lang.Object clone() throws java.lang.CloneNotSupportedException
  而protected权限的含义是:只对同一包中的类和不同包中的子类及间接子类可访问,换句话说就是不同包中的非子类或间接子类不能访问,包含了默认的包访问权限。
  这个地方容易混淆哦
  你可能会问任何类都是Object的子类为什么不能访问呢,对,任何类是他的子类也继承了clone()方法
  但请注意,你那句代码clone()的调用者是谁?是Object本身,即Object对象,正如我们所说,“不同包中的非子类或间接子类不能访问”,这里面也包括了父类本身,你调用者是父类,在不同包中,protected成员对父类不可见哦,所以根本不能用object对象调用clone()
   
  综上,因为在不同包中父类本身不能调用,也找不到protected方法 ,故无法在代码中使用object直接调用clone()方法,

有点难理解,关键在对protected的理解上,因为protected除了本身在继承上的访问权限外,还包含了包访问权限,希望回答你还满意。

原型构造函数

 

http://blog.youkuaiyun.com/kenthong/article/details/5758884

http://www.iteye.com/topic/483469

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值