天天看點

淺談java 對象克隆

package com.mapbar.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 
 * Class CloneDemo.java
 * 
 * Description
 * 
 * Company mapbar 淺克隆,深度克隆,以及對象序列化克隆
 * 
 * author Chenll E-mail: [email protected]
 * 
 * Version 1.0
 * 
 * Date 2012-4-1 上午09:44:06
 */

// 被克隆的類必須自己實作Cloneable 接口,
// 以訓示 Object.clone() 方法可以合法地對該類執行個體進行按字段複制。
// Cloneable 接口實際上是個辨別接口,沒有任何接口方法。

class StudentA implements Cloneable {

  @Override
  public String toString() {
    return "StudentA [id=" + id + ", score=" + score + "]";
  }

  public String getId() {
    return id;
  }

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

  public double getScore() {
    return score;
  }

  public void setScore(double score) {
    this.score = score;
  }

  public StudentA(String id, double score) {
    super();
    this.id = id;
    this.score = score;
  }

  private String id;

  private double score;

  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }

}

// 深度克隆對象,當類存在聚合關系的時候,克隆就必須考慮聚合對象的克隆
class StudentB implements Cloneable {

  @Override
  public String toString() {
    return "StudentB [studentA=" + studentA + ", name=" + name + ", score="
        + score + "]";
  }

  public StudentB(StudentA studentA, String name, double score) {
    super();
    this.studentA = studentA;
    this.name = name;
    this.score = score;
  }

  public StudentA getStudentA() {
    return studentA;
  }

  public void setStudentA(StudentA studentA) {
    this.studentA = studentA;
  }

  public String getName() {
    return name;
  }

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

  public double getScore() {
    return score;
  }

  public void setScore(double score) {
    this.score = score;
  }

  private StudentA studentA;

  private String name;

  private double score;

  @Override
  protected Object clone() throws CloneNotSupportedException {
    StudentB sb = (StudentB) super.clone();
    // 克隆其它聚合屬性
    if (this.studentA != null) {
      sb.studentA = (StudentA) this.studentA.clone();
    }
    return sb;
  }
}
  
public  class CloneDemo{
  /**
   * 所謂對象序列化就是将對象的狀态轉換成位元組流,以後可以通過這些值再生成相同狀态的對象。 這個過程也可以通過網絡實作
   */
  public static Object copyObject(Object oldObj) {
    Object newObj = null;
    try {
      ByteArrayOutputStream bo = new ByteArrayOutputStream();
      ObjectOutputStream oo = new ObjectOutputStream(bo);
      oo.writeObject(oldObj);// 源對象
      ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
      ObjectInputStream oi = new ObjectInputStream(bi);
      newObj = oi.readObject();// 目标對象
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
    return newObj;
  }
  
  public static void main(String[] args) throws CloneNotSupportedException{
    StudentA a = new StudentA("world",10.0);
    System.out.println("before a:"+a.toString());
    StudentA aa = (StudentA) a.clone();
    a.setId("world20");
    a.setScore(20.0);
    System.out.println("after a:"+a.toString());
    System.out.println("clone a:"+aa.toString());
    
    StudentB b = new StudentB(a,"hello",30);
    System.out.println("before b:"+b.toString());
    StudentB bb = (StudentB) b.clone();
    StudentB bbb = (StudentB) copyObject(b);
    b.getStudentA().setId("helloooo");
    b.setScore(50);
    System.out.println("after b:"+b.toString());
    System.out.println("clone b:"+bb.toString());
    System.out.println("copyObject b:"+bbb.toString());
    
    
  }
}