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