`
yangyangmyself
  • 浏览: 229613 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Object的clone()方法、深拷贝、浅拷贝

    博客分类:
  • Java
 
阅读更多
obj.clone().getClass()==obj.getClass(),即它们具有相同的类型。还有一点,因为只是简单的将对象的空间进行复制,所以如果类具有引用类型的实例变量的话,也只是将这个引用进行拷贝,并不复制其引用的对象。这就导致拷贝对象的引用实例变量与原对象的指向相同的对象,这就是传说中的“浅拷贝”。如果实例变量引用的对象是不可变的,类似于String,则拷贝对象与原对象不能互相影响,这样的拷贝是成功的。但是如果引用的是可变对象,它们就会影响彼此,对于成功的拷贝而言,这是不允许的。可以对可变的实例变量对象进行特殊处理,以实现拷贝对象和原对象不能相互影响的“深拷贝”。

      由于Object.clone()方法是protected的,所以它只能在lang包中的类或是其子类的方法内部被调用,所以,如果像下面这样调用,会编译出错,在Person kobe_bak=kobe.clone();报错,说clone只能在Object的protected作用域访问。

class Person implements Cloneable  
{  
    private int age;  
    private String name;  
    private Date birth;  
    public Person(int a,String n,Date b){     
        age=a;  
    name=n;  
    birth=b;  
    }  
      
    public static void main(String[] args){  
        Person kobe=new Person(33,"kobe",new Date());  
        Person kobe_bak=kobe.clone();  
    }  
}  


clone方法的作用域限制不允许我们在其它地方访问,那我们就重写Object的clone方法,并扩大访问作用域为public,在Person类中添加clone的方法重写,调用super.clone(),也就是Object.clone()。

@Override  
public Object clone(){  
    return super.clone();  
}  


然后编译,可以通过,接着运行程序,结果在Person kobe_bak=kobe.clone();抛出CloneNotSupportedException异常。这是因为Java只有一个类实现了Cloneable接口,才表示这个类可以被克隆。所以要想拷贝一个类的对象,必须让它实现Cloneable接口。这个接口只是一个标记接口,没有声明任何方法。

     接下来,让Person类实现Cloneable接口,然后编译,运行,这个对象就被成功的克隆了。所以要想一个类可以被clone,必须满足两点:
第一,它必须实现了Cloneable接口,否则会抛出CloneNotSupportedException异常。
第二,它必须提供一个public的clone方法,也就是重写Object.clone()方法,否则编译不能通过。
第三,对于存在可变域的类,在clone方法中需要对这些可变域进行拷贝。

class Person implements Cloneable  
{  
    private int age;  
    private String name;  
    private Date birth;  
    public Person(int a,String n,Date b){     
        age=a;  
    name=n;  
    birth=b;  
    }  
      
    public static void main(String[] args){  
        Person kobe=new Person(33,"kobe",new Date());  
        Person kobe_bak=kobe.clone();  
    }  
    @Override  
    public Object clone(){  
        Person p=(Person)super.clone();  
        //Date类型的birth域是可变变的,需要对其克隆,进行深拷贝  
        //Date类实现的克隆,直接调用即可  
        p.birth=this.birth.clone();  
        return p;  
    }  
}  


                                            转自:http://www.crazyit.org
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics