JavaA2Z

KAB-studio > プログラミング > JavaA2Z > 浅いコピーとは

浅いコピー

日本語 浅い複製
英語 shallow copy
ふりがな あさいこぴー
フリガナ アサイコピー

解説

インスタンスの複製を作る時に、フィールドインスタンスの複製は作らない方法。
clone()メソッドで複製を作る時の方法の1つ。「シャローコピー」とも言う。
フィールド参照変数の場合、参照値のみコピーする方法を「浅いコピー」と言う。
対して、参照先のインスタンスの複製を作りセットする方法を「深いコピー」と言う。
Objectクラスclone()メソッドによるコピーは浅いコピーである。
 
浅いコピーの場合、全てがコピーされるわけではないため、誤ってコピー元のデータを修正してしまう可能性がある。ただし、深いコピーインスタンスの複製を作るため処理に時間が掛かるというデメリットがあるため、浅いコピーと深いコピー、どちらがいいかは場面によって選択する必要がある。

参考サイト


(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        try
        {
            // 自前で複製を作る場合。
            
            // CopyDataクラスを作ります。
            CopyData data = new CopyData();
            // 浅いコピーされるObjectクラス。
            Object object = new Object();
            System.out.println( object.toString() );
            // java.lang.Object@152544e

            data.setObject( object );

            // clone()メソッドで複製を作ります。
            CopyData newData = (CopyData)data.clone();

            // 中のobjectフィールドが参照するインスタンスは、
            // 先ほど作ったObjectクラスのインスタンスと同じです。
            System.out.println( newData.getObject().toString() );
            // java.lang.Object@152544e

            // このように、浅いコピーでは、インスタンスの
            // 複製は作られません。
        }
        catch( CloneNotSupportedException e )
        {
            e.printStackTrace();
        }

        try
        {
            // Objectクラスのclone()メソッドで複製を作る場合。

            // CopyDataUseObjectCloneクラスを作ります。
            CopyDataUseObjectClone data = new CopyDataUseObjectClone();
            // 浅いコピーされるObjectクラス。
            Object object = new Object();
            System.out.println( object.toString() );
            // java.lang.Object@1e04cbf

            data.setObject( object );

            // clone()メソッドで複製を作ります。
            CopyDataUseObjectClone newData = (CopyDataUseObjectClone)data.clone();

            // 中のobjectフィールドが参照するインスタンスは、
            // 先ほど作ったObjectクラスのインスタンスと同じです。
            System.out.println( newData.getObject().toString() );
            // java.lang.Object@1e04cbf

            // このように、浅いコピーでは、インスタンスの
            // 複製は作られません。
        }
        catch( CloneNotSupportedException e )
        {
            e.printStackTrace();
        }
    }
}

/**
*   コピーするデータクラス。
*/
class CopyData
{
    /** 浅いコピーされるフィールド。 */
    private Object object;

    public void setObject( Object o )
    {
        object = o;
    }

    public Object getObject()
    {
        return object;
    }

    /**
    *   Objectクラスのclone()メソッドをオーバーライドします。
    */
    protected Object clone() throws CloneNotSupportedException
    {
        // 自クラスのインスタンスを作り、フィールドをコピーします。
        // フィールドは参照値をそのままコピーします。
        // これが浅いコピーです。
        CopyData newData = new CopyData();
        newData.object = this.object;
        return newData;
    }
}


/**
*   コピーするデータクラス。
*   ただしObjectクラスのclone()メソッドを使ってコピーします。
*/
class CopyDataUseObjectClone implements Cloneable
{
    /** 浅いコピーされるフィールド。 */
    private Object object;

    public void setObject( Object o )
    {
        object = o;
    }

    public Object getObject()
    {
        return object;
    }

    /**
    *   Objectクラスのclone()メソッドをオーバーライドします。
    */
    protected Object clone() throws CloneNotSupportedException
    {
        // Objectクラスのclone()メソッドで複製します。
        return super.clone();
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        try
        {
            // 自前で複製を作る場合。
            
            // CopyDataクラスを作ります。
            CopyData data = new CopyData();
            // 浅いコピーされるObjectクラス。
            Object object = new Object();
            System.out.println( object.toString() );
            // java.lang.Object@152544e

            data.setObject( object );

            // clone()メソッドで複製を作ります。
            CopyData newData = (CopyData)data.clone();

            // 中のobjectフィールドが参照するインスタンスは、
            // 先ほど作ったObjectクラスのインスタンスと同じです。
            System.out.println( newData.getObject().toString() );
            // java.lang.Object@152544e

            // このように、浅いコピーでは、インスタンスの
            // 複製は作られません。
        }
        catch( CloneNotSupportedException e )
        {
            e.printStackTrace();
        }

        try
        {
            // Objectクラスのclone()メソッドで複製を作る場合。

            // CopyDataUseObjectCloneクラスを作ります。
            CopyDataUseObjectClone data = new CopyDataUseObjectClone();
            // 浅いコピーされるObjectクラス。
            Object object = new Object();
            System.out.println( object.toString() );
            // java.lang.Object@1e04cbf

            data.setObject( object );

            // clone()メソッドで複製を作ります。
            CopyDataUseObjectClone newData = (CopyDataUseObjectClone)data.clone();

            // 中のobjectフィールドが参照するインスタンスは、
            // 先ほど作ったObjectクラスのインスタンスと同じです。
            System.out.println( newData.getObject().toString() );
            // java.lang.Object@1e04cbf

            // このように、浅いコピーでは、インスタンスの
            // 複製は作られません。
        }
        catch( CloneNotSupportedException e )
        {
            e.printStackTrace();
        }
    }
}

/**
*   コピーするデータクラス。
*/
class CopyData
{
    /** 浅いコピーされるフィールド。 */
    private Object object;

    public void setObject( Object o )
    {
        object = o;
    }

    public Object getObject()
    {
        return object;
    }

    /**
    *   Objectクラスのclone()メソッドをオーバーライドします。
    */
    protected Object clone() throws CloneNotSupportedException
    {
        // 自クラスのインスタンスを作り、フィールドをコピーします。
        // フィールドは参照値をそのままコピーします。
        // これが浅いコピーです。
        CopyData newData = new CopyData();
        newData.object = this.object;
        return newData;
    }
}


/**
*   コピーするデータクラス。
*   ただしObjectクラスのclone()メソッドを使ってコピーします。
*/
class CopyDataUseObjectClone implements Cloneable
{
    /** 浅いコピーされるフィールド。 */
    private Object object;

    public void setObject( Object o )
    {
        object = o;
    }

    public Object getObject()
    {
        return object;
    }

    /**
    *   Objectクラスのclone()メソッドをオーバーライドします。
    */
    protected Object clone() throws CloneNotSupportedException
    {
        // Objectクラスのclone()メソッドで複製します。
        return super.clone();
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/07/26
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。