java 对象克隆 及深克隆 浅克隆 及Cloneable接口

来源:互联网 发布:yum安装ruby最新版本 编辑:程序博客网 时间:2024/06/05 16:05

通常子对象是可变的,必须重新定义clone方法来建立一个深拷贝,同时克隆所有的子对象。在这个例子中,hireDay域是一个Date,这时可变的,所以他也需要克隆。(处于这个原因,这个例子使用Date类型的域而不是LocalDate来展示克隆过程。如果hireDay是不可变的LocalDate的一个实例,就无需我们做任何处理了。
对于每一个类,需要确定
1)默认的clone方法是否满足要求。
2)是否可以在可变的子对象上调用clone来修补默认的clone方法
3)是否不该使用clone
实际上第3个选项是默认选项。如果选择第1项或者第2项,类必须:
1)实现Cloneable接口
2)重新定义clone方法,并指定public访问修饰符
Object类中clone方法声明为protected,所以你的代码不能直接调用anObject.clone()。但是,不是所有子类都能访问受保护方法吗?不是所有类都是Object的子类吗?幸运的是,受保护访问的规则比较微妙。子类只能调用受保护的clone方法来克隆他自己的对象。必须重新定义clone为public才能允许所有方法克隆对象。
在这里,Cloneable接口的出现与接口的正常使用并没有关系。具体来说,他没有指定clone方法,这个方法是从Object类继承的。这个接口只是作为一个标记,指示类设计者了解克隆过程。对象对于克隆很偏执,如果一个对象请求克隆,但没有实现这个接口,就会生成一个异常。
Cloneable接口是java提供的一组标记接口(togging interface)之一。应该记得,Comparable等接口的通常用途是确保一个类实现一个或者一组特定的方法。标记接口不包含任何方法;他唯一的作用就是允许在类型查询中使用instanceof:

if(obj instanceof Cloneable)    ...

建议你自己的程序中不要使用标记接口。
即使clone的默认(浅拷贝)实现能够满足要求,还是需要实现Cloneable接口,将clone重新定义为public,再调用super.clone()。下面给出一个例子:

class Employee implements Cloneable{    public Employee clone() throws CloneNotSupportedException    {        return (Employee)super.clone();    }}

与Object.clone提供的浅拷贝相比,前面看到的clone方法并没有为他增加任何功能。只是放这个方法是公有的。要建立深拷贝,还需要做更多的工作,克隆对象中可变的实例域

//在java SE 1.4之前,clone方法的返回类型总是Object,而现在可以为你的clone方法指定正确的返回类型:如(Employee)super.clone();class Employee implements Cloneable{    ...  //Employee 类的其他功能    //以下为Employee类的克隆功能的实现    public Employee clone() throws CloneNotSupportedException    {        Employee cloned=(Employee)super.clone();  //浅克隆        //在浅克隆的基础上深化克隆        cloned.hireDay=(Date)this.hireDay.clone();        return cloned;    }}

如果在一个对象上调用clone,但这个对象的类并没有实现Cloneable接口,Object类的clone方法就会抛出一个CloneNotSupportedException。当然,Employee和Date类实现了Cloneable接口,所以不会抛出这个异常。不过,编译器并不了解这一点,因此,我们声明了这个异常:

public Employee clone() throws CloneNotSupportedException

捕获这个异常是不是更好一点?

 public Employee clone() {     try    {        Employee cloned=(Employee)supper.clone();        ...    }    catch(CloneNotFoundedException e)    {        return null;    }}
阅读全文
0 0
原创粉丝点击