java.lang.Cloneable

来源:互联网 发布:js全局变量和局部变量 编辑:程序博客网 时间:2024/05/16 14:44

Cloneable接口继承了java.lang。

Cloneable 的用途 

public interface Cloneable 

    Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。 
如果一个类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。  
如果在没有实现 Cloneable 接口的实例上调用 Object的 clone 方法,则会导致抛出 CloneNotSupportedException异常。  
按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的)。请参阅 Object.clone(),以获得有关重写此方法的详细信息。  
注意,此接口不 包含 clone 方法。因此,因为某个对象实现了此接口就克隆它是不可能的。即使 clone 方法是反射性调用的,也无法保证它将获得成功。 


这里分析一下这个接口的用法
java种clone的含义(或者说是目标)
假设x是一个非空对象,应该有:
x.clone()!=x 为true,就是说他们不是同一个对象.
x.clone().getClass()==x.getClass() 为true,他们是同一个类型Class.
x.equals(x.clone()) 为true,逻辑上应该相当.

clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才

可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException.
Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例.

pubilc class Unsupported{
   public Object clone(){
  Object obj;
        try {
        obj=super.clone();
 }
     catch (CloneNotSupportedException ex) {
        ex.printStackTrace(); //Exception was thrown
     }
 return obj;//返回的是null
   }
}
加上 implements Cloneable 就可以了.
可不可以不实现这个接口,但是覆盖Clone方法.
pubilc class Unnormal{
   public Object clone(){
 return new Unnormal();
   }
}
这样肯定没有问题的,不过已经和java中的clone机制没有关系了.
下面举一个例子说明浅拷贝和深拷贝:
public class ShallowCopy implements Cloneable{
     private Date begin;
     public Date getBegin(){return this.begin;}
     public void setBegin(Date d){this.begin=d;}
     public Object clone(){
 Object obj=null;
        try
 {
  obj=super.clone();
  }
        catch (CloneNotSupportedException ex) {
        ex.printStackTrace(); 
     }
 return obj;
     }
}
public class DeepCopy implements Cloneable{
 private Date begin;
     public Date getBegin(){return this.begin;}
     public void setBegin(Date d){this.begin=d;}
     public Object clone(){
 DeepCopy obj=null;
 try
 {
  obj=(DeepCopy)super.clone();
  }
        catch (CloneNotSupportedException ex) {
        ex.printStackTrace(); 
     }
 obj.setBegin((Date)this.getBegin().clone());
 return obj;
    }
}


Object.clone()方法是 procted类型的. 只有当某个类直接调用 this.clone() 时,因为任何类都是Object对象的子类, 此时这个类必须实现Cloneable接口,否则会跑不支持Cloneable接口异常, 而在当前类里面调用别的对象的clone()时,是不需要实现Cloneable接口的。



和Serializable的比较

使用Serializable同样可以做到对象的clone。但是:
Cloneable本身就是为clone设计的,虽然有一些缺点,但是如果它可以clone的话无疑用它来做clone比较合适。如果不行的话用原型构造函数,或者静态copy方法也可以。

Serializable制作clone的话,添加了太多其它的东西,增加了复杂性。
1 所有的相关的类都得支持Serializable。这个相比支持Cloneable只会工作量更大
2 Serializable添加了更多的意义,除了提供一个方法用Serializable制作Clone,该类等于也添加了其它的public API,如果一个类实现了Serializable,等于它的2进制形式就已经是其API的一部分了,不便于该类以后内部的改动。
3 当类用Serializable来实现clone时,用户如果保存了一个老版本的对象2进制,该类升级,用户用新版本的类反系列化该对象,再调用该对象用Serializable实现的clone。这里为了一个clone的方法又引入了类版本兼容性的问题。不划算。


性能

不可否认,JVM越来越快了。
但是系统默认的native实现还是挺快的。
clone一个有100个元素的int数组,用系统默认的clone比静态copy方法快2倍左右。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 走路有尿溢出来怎么办 篮球气嘴漏气了怎么办 暗线插座盒坏了怎么办 焊过电焊眼睛疼怎么办 烧电焊后眼睛痛怎么办? 焊完电焊眼睛疼怎么办 烧电焊后眼睛痛怎么办 用电焊后眼睛痛怎么办 看电焊后眼睛痛怎么办 眼睛焊电焊很痛怎么办 电焊没带眼睛痛怎么办 有东西进眼睛了怎么办 眼睛有东西磨眼怎么办 怀孕了眼睛肿疼怎么办 眼睛疼又红血丝怎么办 用眼过度眼睛疼怎么办 眼睛玩手机视力下降怎么办 看手机眼睛疼该怎么办 眼睛眨一下就痛怎么办 着火了怎么办教案详案 汽车尾灯磕破了怎么办 后尾灯灯罩裂了怎么办 七氟丙烷喷伤了怎么办 冒险岛2fps低怎么办 虐杀原形2很卡怎么办 玩虐杀原形2卡怎么办 虐杀原形2闪退怎么办 电脑显示不出u盘怎么办 电脑不显示u盘怎么办 u盘在电脑不显示怎么办 笔记本不识别u盘怎么办 u盘突然识别不了怎么办 xp电脑读不出u盘怎么办 电脑无法读取u盘怎么办 win7电脑不读u盘怎么办 电脑识别不出u盘怎么办 u盘电脑读不出来怎么办 u盘突然无法识别怎么办 u盘电脑无法识别怎么办 系统无法识别u盘怎么办 手机u盘无法识别怎么办