マンガで分かる Java入門講座

第10章 クラスとオブジェクト3
10-3. Objectクラス3 オブジェクトの複製

「Object」クラスのメソッド「clone」の紹介と、その挙動について説明します。

● オブジェクトの複製

 オブジェクトの複製には、java.lang.Objectの「clone」メソッドを使います。cloneメソッドを自作クラスで使う場合は、cloneメソッドをオバーライドして、「Cloneable」インターフェースを実装しなければなりません。

 Objectのcloneメソッドは、オブジェクトの値や参照を保存しているインスタンスを複製して、オブジェクトを複製してくれます。そのオブジェクトを自作クラスにキャストすれば、オブジェクトが複製されます。

ソースコード)オブジェクトの複製
package sample;

public class MyClass implements Cloneable {
    public int n = 0;

    // cloneのオーバーライド
    @Override
    public MyClass clone() {
        MyClass res = null;
        try {
            // クローン
            res = (MyClass)super.clone();
        } catch (CloneNotSupportedException e) {
            // 発生しないだろうと思われるエラー処理
            throw new InternalError(e.toString());
        }
        return res;
    }
}

● 参照型のフィールドの複製

 cloneはインスタンスを複製します。しかし、参照型のフィールドでは、オブジェクトへの参照が複製されるだけです。

図)参照型のフィールドの複製
┏MyClass ━┓                    ┏MyClass ━┓
┃     ┃                    ┃     ┃
┃     ┠─○n   値   →複製→   値  n○─┨     ┃
┃     ┠─○iArr 参照  →複製→  参照 iArr○─┨     ┃
┗━━━━━┛     │         │     ┗━━━━━┛
            └────┬────┘
                 ↓
               ┏━━┓同じ配列を参照
               ┃配列┃
               ┗━━┛

 こういった複製を「シャローコピー(浅い複製)」と呼びます。

 フィールドのオブジェクトも複製したい場合は、clone内でオブジェクトを複製する処理を自前で書く必要があります。

 オブジェクトの内容も複製することを「ディープコピー(深い複製)」と呼びます。

ソースコード)参照型のフィールドの複製
package sample;

public class MyClass implements Cloneable {
    public int n = 0;
    public int[] iArr = {1, 2, 3};

    // cloneのオーバーライド
    @Override
    public MyClass clone() {
        MyClass res = null;

        try {
            // クローン
            res = (MyClass)super.clone();
        } catch (CloneNotSupportedException e) {
            // 発生しないだろうと思われるエラー処理
            throw new InternalError(e.toString());
        }

        // ディープコピー
        res.iArr = iArr.clone();
        return res;
    }
}

ソースコード)MyClass.cloneの利用
MyClass mc1 = new MyClass();
MyClass mc2 = mc1.clone();

mc1.n = 4;
mc1.iArr[0] = 5;

System.out.println(
    mc1.n + " " + Arrays.toString(mc1.iArr)
    + "\n" +
    mc2.n + " " + Arrays.toString(mc2.iArr)
);

出力)MyClass.cloneの利用
4 [5, 2, 3]
0 [1, 2, 3]

この講座のマンガ部分は「箱人形マンガ(Box Comic) 」で作成しています。
作成:2013/06/05  更新:2015/08/09  [Permalink]