



目次
「ディープコピー」と「シャローコピー」の違い
シャローコピーとは
シャローコピーとは浅い(shallow)コピーと呼ばれ、実体(データ)のコピーを行わないで、オブジェクトをコピーする方式です。要するに見せかけの複製を作るコピーです。
オブジェクトはメモリ上にある実体(データ)を参照します。シャローコピーでは、実体(データ)のコピーを行わないので、シャローコピーで生成されたオブジェクトは、コピー元オブジェクトと同じ実体(データ)を参照することとなります。
シャローコピーで作られたオブジェクトは、参照している実体(データ)が同じです。ということは、どちらかのオブジェクトを変更したら、もう片方のオブジェクトも変更されます。なぜなら同じ実体(データ)を参照しているからです。
スポンサーリンク
ディープコピーとは
ディープコピーとは深い(deep)コピーと呼ばれ、実体(データ)も含めてオブジェクトをコピーする方式です。要するに完全な複製を作るコピーです。
オブジェクトはメモリ上にある実体(データ)を参照します。ディープコピーでは、オブジェクトと参照する実体(データ)をコピーします。そのため、コピー元とコピー先は別々の実体(データ)を参照することとなります。
ディープコピーで作られたオブジェクトは、別々の実体(データ)を参照します。そのため、どちらかのオブジェクトを変更しても、もう片方のオブジェクトには影響を与えません。
「ディープコピー」と「シャローコピー」のコピー例
シャローコピーのコピー例
コピー対象のオブジェクト(データを格納する箱)は以下とします。
package entity; public class User { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
シャローコピーのコピー例
package main; import entity.User; public class Start { public static void main(String[] args) { User user1 = new User(); // user1の名前を設定 user1.setName("変更前の名前"); // シャローコピー User user2 = user1; // user2の名前を変更 user2.setName("変更後の名前"); System.out.println("user1の名前:" + user1.getName()); System.out.println("user2の名前:" + user2.getName()); } }
スポンサーリンク
実行結果は以下のように「コピー元の名前」「コピー先の名前」には「変更後の名前」が設定されています。
これはどちらもメモリ上にある同じ実体(データ)を参照していることが理由です。
コピー元の名前:変更後の名前 コピー先の名前:変更後の名前
ディープコピーのコピー例
コピー対象のオブジェクト(データを格納する箱)は以下とします。Javaが提供しているclone(複製)を作るインタフェースである「Cloneable」をimplements しています。
package entity; public class User2 implements Cloneable { private String name; @Override public User2 clone() { User2 user2 = null; try { user2 = (User2) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return user2; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
ディープコピーのコピー例
package main; import entity.User2; public class Start2 { public static void main(String[] args) { User2 user2 = new User2(); // user1の名前を設定 user2.setName("変更前の名前"); // ディープコピー User2 copyUser2 = user2.clone(); // user2の名前を変更 copyUser2.setName("変更後の名前"); System.out.println("コピー元の名前:" + user2.getName()); System.out.println("コピー先の名前:" + copyUser2.getName()); } }
実行結果は以下のように「コピー元の名前」「コピー先の名前」には別々の名前が設定されています。
これはシャローコピーとは違い、メモリ上にある別の実体(データ)を参照していることが理由です。
コピー元の名前:変更前の名前 コピー先の名前:変更後の名前