



目次
「ディープコピー」と「シャローコピー」の違い
シャローコピーとは
シャローコピーとは浅い(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());
  }
}実行結果は以下のように「コピー元の名前」「コピー先の名前」には別々の名前が設定されています。
これはシャローコピーとは違い、メモリ上にある別の実体(データ)を参照していることが理由です。
コピー元の名前:変更前の名前
コピー先の名前:変更後の名前 
 