2021-04-18 10:56  阅读(94)
文章分类:Java 基础教程 文章标签:JavaJava 教程
©  原文作者:w3cschool 原文地址:https://www.w3cschool.cn/java/java-class-instance.html

Java面向对象设计 - Java Object.Clone方法

Java不提供克隆(复制)对象的自动机制。

克隆对象意味着逐位复制对象的内容。

要支持克隆操作,请在类中实现clone()方法。

Object类中的clone()方法的声明如下:

    protected  Object clone()  throws   CloneNotSupportedException
    

clone()方法声明为protected。因此,我们不能从客户端代码调用它。以下代码无效:

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

我们需要在类中声明clone()方法public克隆类的对象。

它的返回类型是Object。这意味着您将需要转换clone()方法的返回值。

假设MyClass是可克隆的。克隆代码将如下所示:

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

Object类中的clone()方法会抛出CloneNotSupportedException。

要调用clone()方法,我们需要将调用放在try-catch块中,或者重新抛出异常。

例子

以下代码显示了如何实现克隆方法。

    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());
      }
    }
    

上面的代码生成以下结果。

2021041810513_1.png

例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());
      }
    }
    

上面的代码生成以下结果。

202104181058_2.png

例3

ShallowClone类的clone()方法中的代码与MyClass类的clone()方法相同。

当ShallowClone类使用super.clone()调用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());
      }
    }
    

上面的代码生成以下结果。

202104181056_3.png

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Java Object.Clone方法
上一篇
Java Object.toString方法
下一篇
Java Object.Finalize方法