ホームページ  >  記事  >  Java  >  Java におけるオブジェクトのシャロー クローン作成とディープ クローン作成について詳しく説明します。

Java におけるオブジェクトのシャロー クローン作成とディープ クローン作成について詳しく説明します。

黄舟
黄舟オリジナル
2017-07-21 16:08:061363ブラウズ

この記事では、主に Java オブジェクトのクローン作成に関する関連情報を紹介します。必要な方は、これを参考にしてください。

1.オブジェクトの

(1) クラスをクローンする必要がある場合は、Object クラスの clone メソッドをオーバーライドし、Cloneable インターフェイス (識別インターフェイス。メソッドを実装する必要はありません) を実装する必要があります。 (2) オブジェクトがクローンを作成する必要があるものは別の参照オブジェクトを維持しますが、シャロー クローン作成では別の参照ペアのクローンを作成しませんが、維持されている別の参照オブジェクトのアドレスを直接コピーします。 (3) オブジェクトの浅いクローン作成ではコンストラクターは呼び出されません。


以下は、オブジェクトの浅いクローン作成の例です:

package com.clone;

import java.io.Serializable;

/**
 * Description:
 * 实现了Cloneable接口,并重写Object类的clone方法。
 * 
 * @author lee
 * */
public class CloneDemo1 implements Cloneable,Serializable{

  //该克隆类封装的信息
  public int id;
  public String name;
  public Address address;

  /**
   * Desciption:
   * 默认构造器
   * 
   * */
  public CloneDemo1(){}

  /**
   * Description:
   * 初始化id,name的构造器
   * 
   * @param id id
   * @param name 名字
   * @param address 地址
   * */
  public CloneDemo1(int id, String name, Address address){
    this.id=id;
    this.name=name;
    this.address = address;
  }

  /**
   * Descriptin:
   * 重写Object类的clone方法。
   * if the object's class does not support the Cloneable interface.
   * Subclasses that override the clone method can also throw this exception 
   * to indicate that an instance cannot be cloned.
   * 
   * @throws CloneNotSupportedException 
   * */
  @Override
  public Object clone() throws CloneNotSupportedException{
    return super.clone();
  }

  /**
   * Description:
   * 重写toString方法
   * 
   * @return "id="+id+", name="+name
   * */
  @Override
  public String toString(){
    return "id="+id+", name="+name+", address:"+address.getAddress();
  }

  /**
   * Description:
   * 主方法
   * 
   * */
  public static void main(String[] args) throws CloneNotSupportedException{

    CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
    //c2 复制了c1的地址,并没有复制整个c1对象
    CloneDemo1 c2 = c1;
    //c3 对象的浅克隆,复制了整个对象
    CloneDemo1 c3 = (CloneDemo1)c1.clone();

    //当对象c1改变其name或者id的时候,c2也会自动改变。
    //因为c2只是复制了c1的地址,并非复制了c1的整个对象。
    //相应的c3则不会随着c1改变而改变,意味着c3将c1整个对象克隆一份出来。

    //当是,对象的浅克隆不会克隆被克隆对象当中的引用对象。
    //因此c1改变其中的Address的引用对象时,c2,c3也会跟着改变。
    c1.setName("cc");
    c1.address.setAddress("上海");
    System.out.println(c1+"\n"+c2+"\n"+c3);



  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

}

/**
 * Description:
 * 一个封装着地址的类
 * 
 * @author lee
 * */
class Address implements Serializable{
  public String address;

  /**
   * Description:
   * 默认构造器
   * 
   * */
  public Address(){}

  /**
   * Description:
   * 初试化address
   * 
   * @param address 地址
   * */
  public Address(String address){
    this.address = address;
  }

  //address的set和get方法
  public String getAddress() {
    return address;
  }

  public void setAddress(String address) {
    this.address = address;
  }
}

2. オブジェクトのディープクローン作成

は、オブジェクトの入出力ストリームを使用して、オブジェクトをファイルに書き込みます。 、オブジェクト情報を読み取ります。これはオブジェクトのディープ クローンです。

オブジェクトの浅いクローン作成では、クローンされたオブジェクト内の参照オブジェクトがクローンされるのではなく、そのアドレスが直接コピーされます。したがって、複製されたオブジェクト内の参照型を複製するには、オブジェクトの詳細な複製が必要です。


オブジェクトのディープクローン作成では、オブジェクトのシリアル化入出力を使用します。


コードは次のとおりです:


package com.clone;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Description:
 * 实现对象的深克隆
 * 
 * @author lee
 * */
public class CloneDemo2 {

  /**
   * Description:
   * 将对象输出到一个文件当中。
   * 
   * @param c 需要被写到文件当中的对象。
   * */
  public static void writeObject(CloneDemo1 c){

    ObjectOutputStream out = null;
    try{

      //将对象输出在一个object.txt文件当中
      out = new ObjectOutputStream(new FileOutputStream("./object.txt"));
      out.writeObject(c);

    }catch(IOException e){
      System.out.println("写入对象的时候发生了错误。");
      e.printStackTrace();
    }finally{

      //关闭资源
      try{
        out.close();
      }catch(IOException e){
        e.printStackTrace();
      }
    }


  }

  /**
   * Description:
   * 从文件中读取出一个对象来,并返回。
   * 
   * @return c 返回一个对象。
   * */
  public static CloneDemo1 readObject(){

    CloneDemo1 c = null;
    ObjectInputStream input = null;
    try{
      //从object.txt文件中读取一个对象出来
      input = new ObjectInputStream(new FileInputStream("./object.txt"));
      c = (CloneDemo1)input.readObject();

    }catch(IOException | ClassNotFoundException e){
      e.printStackTrace();
      System.out.println("读取对象的时候发生了错误。");
    }finally{
      //关闭资源
      try{
        input.close();
      }catch(IOException e){
        e.printStackTrace();
      }
    }
    return c;
  }
  /**
   * Description:
   * 主方法
   * 
   * @throws CloneNotSupportedException 
   * */
  public static void main(String[] args) throws CloneNotSupportedException {
    CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
    //c2 对象的浅克隆
    CloneDemo1 c2 = (CloneDemo1)c1.clone();
    //c3对象的深克隆
    writeObject(c1);
    CloneDemo1 c3 = readObject();

    //因为对象的深克隆同时也克隆了被克隆对象维护的另外一个对象
    //所以,当c1改变其当中的维护的另外一个对象的时候,c3不会随之改变。
    //而c2位浅克隆,其维护的另外一个对象只是复制了c1维护的对象的地址,因此会随着c1的改变而改变。
    c1.address.setAddress("上海");
    System.out.println(c1+"\n"+c2+"\n"+c3);

  }

}

オブジェクトのシリアル化には、Serializable インターフェイスの実装が必要です。

以上がJava におけるオブジェクトのシャロー クローン作成とディープ クローン作成について詳しく説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。