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

通常子对象是可变的,必须重新定义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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值