clone(); 深拷贝、浅拷贝

Clone

Cloneable 接口
如果直接把一个变量赋给另一个变量,例如下面这句,e1,e2将指向同一个引用对象,如果改变e2的值,e1的值同样将被改变。

      Employee e2 = e1;

因此,为了使e1,e2可以各自改变状态,需要使用clone方法。clone()完全创造出一个新的对象,有自己的新的地址,只不过初始信息是和原对象是一样的。

   public Employee clone() throws CloneNotSupportedException
   {
      // call Object.clone()
      Employee cloned = (Employee) super.clone();

      // clone mutable fields
      cloned.hireDay = (Date) hireDay.clone();

      return cloned;
   }

Cloneable接口是空的,不包括任何常量和抽象方法。实现Cloneable接口的类标记为可克隆的,这个类必须覆盖在Object类中定义的clone( )方法。

Object中的源码:

    protected native Object clone() throws CloneNotSupportedException;

浅拷贝

如果对象中的所有数据域都是数值或基本类型,使用clone拷贝域没有任何问题。但如果在对象中包含了子对象的引用,clone不会拷贝子对象,只是把两个域引用同一个子对象。

比如说,我们上面说到的Employee,它有一个string域、一个Date域。String域不允许改变的类,拷贝不会出错。但Date类是可变的子对象,直接拷贝会出错!因此必须重新定义clone方法

对每一个类,我们要先做出以下判断:

  1. 默认的clone方法是否满足要求
  2. 默认的clone方法是否能够通过调用可变子对象的clone得到修补。
  3. 是否不应该使用clone
     

深拷贝

深拷贝和浅拷贝正好相反,在克隆一个对象时,其内的引用也发生了相应的克隆,都会产生完全没有关联的对象。即在对象中包含了子对象的引用,clone也会拷贝子对象。

    public EmployeeForClone clone() throws CloneNotSupportedException
    {
        // call Object.clone()
        EmployeeForClone cloned = (EmployeeForClone) super.clone();

        // clone mutable fields
        cloned.hireDay = (Date) hireDay.clone();

        return cloned;
    }

hireDay就是我们上边说的Date对象,重新修改代码后实现了深拷贝。

只要在clone中含有没有实现Cloneable接口的对象,Object类的clone方法就会抛出一个CloneNot-SupportException 异常。因此需要声明 ... throws CloneNotSupportedException

扫描二维码关注公众号,回复: 6542268 查看本文章

猜你喜欢

转载自blog.csdn.net/L20902/article/details/92798567