烏滑稽

ブログはじめました(迫真)

Javaのオブジェクト複製の動作確認

今更ながら躓いたので動作チェックのメモ。

import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
・・・
/**
 * オブジェクト同士が同じオブジェクトか判断するとき
 * hashCode()がオーバーライドされていて使えないときは
 * System.identityHashCode()を使うといい.
 */
@Test
public final void objectCheck() {
  List original = new ArrayList();
  List original2 = original;
  List copyConst = new ArrayList(original);
  System.out.println("original = " + System.identityHashCode(original));
  System.out.println("original2 = " + System.identityHashCode(original2));
  System.out.println("copyConst = " + System.identityHashCode(copyConst));
}

/**
 * Objectクラスのclone()はあくまでもshallowコピーなので
 * メンバが参照型でインスタンスが入っている場合clone()を使うと共有してしまう.
 */
@Test
public final void shallowCopyTest() {
  CopySareru shallow1 = new CopySareru();
  CopySareru shallow2 = shallow1.clone();
  System.out.println("shallow1.getMemberAddress() = " + shallow1.getMemberAddress());
  System.out.println("shallow2.getMemberAddress() = " + shallow2.getMemberAddress());
}

/**
 * shallowコピーとはいえコピー対象同士のオブジェクトは別物なので
 * clone()後にメンバをインスタンス化すればメンバを共有することはない.
 */
@Test
public final void copyAndInitTest() {
  CopySareru deep1 = new CopySareru();
  CopySareru deep2 = deep1.clone();
  deep1.init();
  deep2.init();
  System.out.println("deep1.getMemberAddress() = " + deep1.getMemberAddress());
  System.out.println("deep2.getMemberAddress() = " + deep2.getMemberAddress());
}


class CopySareru implements Cloneable {
  private List member;

  public CopySareru() {
    member = new ArrayList();
  }

  public void init() {
    member = new ArrayList();
  }

  public int getMemberAddress() {
    return System.identityHashCode(member);
  }

  public CopySareru clone() {
    CopySareru cs = null;
    try {
      cs = (CopySareru) super.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return cs;
  }
}

結果

Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.021 sec
original = 1689843956
original2 = 1689843956
copyConst = 977993101
shallow1.getMemberAddress() = 5592464
shallow2.getMemberAddress() = 5592464
deep1.getMemberAddress() = 1830712962
deep2.getMemberAddress() = 1112280004

参考: Javaクローンメモ(Hishidama's Java Cloneable Memo)