Javaでオブジェクトのディープクローンを行う
ディープクローンという言葉があるかどうか分かりませんが。。
オブジェクトのディープコピーを返すメソッドを作成します。
方法はいくつかあるかと思いますが、ここではSerializableインタフェースを用いてやってみます。
public static Object deepClone(Serializable s) { if (s == null) { return null; } byte[] bytes = null; try ( ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); ) { oos.writeObject(s); bytes = baos.toByteArray(); } catch (IOException ex) { // TODO 例外処理 } Object ret = null; if (bytes != null) { try ( ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); ) { ret = ois.readObject(); } catch (IOException | ClassNotFoundException ex) { // TODO 例外処理 } } return ret; }
テストコードは以下の通りです。
@Test public void testDeepClone() { // テストデータの準備 int a = 1; String b = "あいうえお"; int c_a = 2; String c_b = "かきくけこ"; TestDto o1 = new TestDto(); o1.setA(a); o1.setB(b); ChildDto child = new ChildDto(); child.setC_a(c_a); child.setC_b(c_b); o1.setChild(child); // 対象メソッドの実行 Object o2 = DeepCloneUtil.deepClone(o1); // テスト結果の検証 assertNotNull(o2); assertNotSame(o1, o2); assertTrue(o2 instanceof TestDto); assertEquals(a, ((TestDto)o2).getA()); assertEquals(b, ((TestDto)o2).getB()); assertNotNull(((TestDto)o2).getChild()); assertNotSame(child, ((TestDto)o2).getChild()); assertEquals(c_a, ((TestDto)o2).getChild().getC_a()); assertEquals(c_b, ((TestDto)o2).getChild().getC_b()); }
public class TestDto implements Serializable { private int a; private String b; private ChildDto child; public ChildDto getChild() { return child; } public void setChild(ChildDto child) { this.child = child; } public int getA() { return a; } public void setA(int a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } }
public class ChildDto implements Serializable { private int c_a; private String c_b; public int getC_a() { return c_a; } public void setC_a(int c_a) { this.c_a = c_a; } public String getC_b() { return c_b; } public void setC_b(String c_b) { this.c_b = c_b; } }