Java中clone()方法的重要性?

克隆() 方法被用来创建它实现了一个类的一个对象的副本Cloneable的 接口。默认情况下,它会按字段进行复制, 因为Object类对对象调用此方法的特定类的成员没有任何了解。因此,如果类仅具有原始数据类型成员,则将创建对象的新副本,并返回对新对象副本的引用。但是,如果类包含任何类类型的成员,则仅复制对那些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象。

如果尝试在未实现Cloneable 接口的类的对象上调用clone()方法,则将获得CloneNotSupportedException 。该接口是标记接口,并且该接口的实现仅表示可以在实现类的对象上调用Object.clone()方法。

语法

protected Object clone() throws CloneNotSupportedException

我们可以通过clone()两种方式实现该方法

浅拷贝

如果该类也具有非原始数据类型成员,则这是Object.clone()方法提供的默认克隆功能的结果。在“浅复制”的情况下,克隆的对象还引用与原始对象所引用的对象相同的对象,因为仅复制对象引用而不引用对象。

示例

public class ShallowCopyTest {
   public static void main(String args[]) {
      A a1 = new A();
      A a2 = (A) a1.clone();
      a1.sb.append("Nhooo!");
      System.out.println(a1);
      System.out.println(a2);
   }
}
class A implements Cloneable {
   public StringBuffer sb = new StringBuffer("Welcome to ");
      public String toString() {
         return sb.toString();
      }
   public Object clone() {
      try {
         return super.clone();
      } catch(CloneNotSupportedException e) {
      }
      return null;
   }
}

输出结果

Welcome to Nhooo!
Welcome to Nhooo!


深拷贝

对于具有非原始类型成员的类,我们需要重写clone() 方法以实现Deep Copy,因为它也需要克隆成员对象,而默认的克隆机制无法做到这一点。

示例

public class DeepCopyTest {
   public static void main(String args[]) {
      A a1 = new A();
      A a2 = (A) a1.clone();
      a1.sb.append(" nhooo!");
      System.out.println(a1);
      System.out.println(a2);
   }
}
class A implements Cloneable {
   public StringBuffer sb = new StringBuffer("Welcome to ");
   public String toString() {
      return sb.toString();
   }
   public Object clone() {
      try {
         A a = (A) super.clone();
         a.sb = new StringBuffer(sb.toString());
         return a;
      }
      catch(CloneNotSupportedException e) {
      }
      return null;
   }
}

输出结果

Welcome to nhooo!
Welcome to