Java Object.Clone方法

2022-08-09 16:23 更新

Java面向?qū)ο笤O(shè)計 - Java Object.Clone方法


Java不提供克隆(復(fù)制)對象的自動機制。

克隆對象意味著逐位復(fù)制對象的內(nèi)容。

要支持克隆操作,請在類中實現(xiàn)clone()方法。

Object類中的clone()方法的聲明如下:

protected  Object clone()  throws   CloneNotSupportedException

clone()方法聲明為protected。因此,我們不能從客戶端代碼調(diào)用它。以下代碼無效:

Object obj  = new Object();
Object clone = obj.clone(); // Error. Cannot  access protected clone() method

我們需要在類中聲明clone()方法public克隆類的對象。

它的返回類型是Object。這意味著您將需要轉(zhuǎn)換clone()方法的返回值。

假設(shè)MyClass是可克隆的??寺〈a將如下所示:

MyClass mc  = new MyClass();
MyClass clone = (MyClass)mc.clone(); // Need to use  a  cast

Object類中的clone()方法會拋出CloneNotSupportedException。

要調(diào)用clone()方法,我們需要將調(diào)用放在try-catch塊中,或者重新拋出異常。


例子

以下代碼顯示了如何實現(xiàn)克隆方法。

class MyClass implements Cloneable {
  private double value;

  public MyClass(double value) {
    this.value = value;
  }

  public void setValue(double value) {
    this.value = value;
  }

  public double getValue() {
    return this.value;
  }

  public Object clone() {
    MyClass copy = null;
    try {
      copy = (MyClass) super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return copy;
  }
}

public class Main {
  public static void main(String[] args) {
    MyClass dh = new MyClass(100.00);

    MyClass dhClone = (MyClass) dh.clone();

    System.out.println("Original:" + dh.getValue());
    System.out.println("Clone :" + dhClone.getValue());

    dh.setValue(200.00);
    dhClone.setValue(400.00);

    System.out.println("Original:" + dh.getValue());
    System.out.println("Clone :" + dhClone.getValue());
  }
}

上面的代碼生成以下結(jié)果。

Original:100.0
Clone :100.0
Original:200.0
Clone :400.0

例2

以下代碼不從clone方法返回對象類型,該方法僅在Java 5或更高版本中編譯。

class MyClass  implements Cloneable  {
    public MyClass clone()  { 
       Object copy  = null;
       return  (MyClass)copy;
    }
}

下面的代碼展示了如何做淺層克隆。

class MyClass implements Cloneable {
  private double value;

  public MyClass(double value) {
    this.value = value;
  }

  public void setValue(double value) {
    this.value = value;
  }

  public double getValue() {
    return this.value;
  }

  public Object clone() {
    MyClass copy = null;
    try {
      copy = (MyClass) super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return copy;
  }
}

class ShallowClone implements Cloneable {
  private MyClass holder = new MyClass(0.0);

  public ShallowClone(double value) {
    this.holder.setValue(value);
  }

  public void setValue(double value) {
    this.holder.setValue(value);
  }

  public double getValue() {
    return this.holder.getValue();
  }

  public Object clone() {
    ShallowClone copy = null;
    try {
      copy = (ShallowClone) super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return copy;
  }
}

public class Main {
  public static void main(String[] args) {
    ShallowClone sc = new ShallowClone(100.00);
    ShallowClone scClone = (ShallowClone) sc.clone();

    System.out.println("Original:" + sc.getValue());
    System.out.println("Clone :" + scClone.getValue());

    sc.setValue(200.00);

    System.out.println("Original:" + sc.getValue());
    System.out.println("Clone :" + scClone.getValue());
  }
}

上面的代碼生成以下結(jié)果。

例3

ShallowClone類的clone()方法中的代碼與MyClass類的clone()方法相同。

當(dāng)ShallowClone類使用super.clone()調(diào)用Object類的clone()方法時,它會接收自身的淺拷貝。也就是說,它與其克隆共享其實例變量中使用的DoubleHolder對象。

在深層克隆中,您需要克隆對象的所有引用實例變量引用的所有對象。

class MyClass implements Cloneable {
  private double value;

  public MyClass(double value) {
    this.value = value;
  }

  public void setValue(double value) {
    this.value = value;
  }

  public double getValue() {
    return this.value;
  }

  public Object clone() {
    MyClass copy = null;
    try {
      copy = (MyClass) super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return copy;
  }
}

class DeepClone implements Cloneable {
  private MyClass holder = new MyClass(0.0);

  public DeepClone(double value) {
    this.holder.setValue(value);
  }

  public void setValue(double value) {
    this.holder.setValue(value);
  }

  public double getValue() {
    return this.holder.getValue();
  }
  public Object clone() {
    DeepClone copy = null;
    try {
      copy = (DeepClone) super.clone();
      copy.holder = (MyClass) this.holder.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return copy;
  }
}

public class Main {
  public static void main(String[] args) {
    DeepClone sc = new DeepClone(100.00);
    DeepClone scClone = (DeepClone) sc.clone();

    System.out.println("Original:" + sc.getValue());
    System.out.println("Clone :" + scClone.getValue());

    sc.setValue(200.00);

    System.out.println("Original:" + sc.getValue());
    System.out.println("Clone :" + scClone.getValue());
  }
}

上面的代碼生成以下結(jié)果。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號