Menu
Coddy logo textTech

clone() メソッド

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 43/87。

clone() メソッドは、オブジェクトのコピーを作成します。これを使用するには、クラスが Cloneable インターフェースを実装し、Object クラスの clone() メソッドをオーバーライドする必要があります。

public class Person implements Cloneable {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public Person clone() {
        try {
            return (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

これで、オブジェクトの独立したコピーを作成できるようになります:

Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy は同じ値を持つ別のオブジェクトです

デフォルトでは、clone()シャローコピーを実行します。これは、プリミティブ値と参照をコピーすることを意味します。オブジェクトがフィールドとして他のオブジェクトを含んでいる場合、オリジナルとクローンの両方が同じネストされたオブジェクトを参照します。ネストされたオブジェクトを含む真に独立したコピーを作成するには、clone() メソッド内でそれらのネストされたオブジェクトもクローンすることで、ディープコピーを実装する必要があります。

challenge icon

チャレンジ

簡単

オブジェクトのクローニングを実演するドキュメント管理システムを構築しましょう。独立したコピーを作成するためにクローン可能な Document クラスを作成し、オリジナルをそのまま保持しながらドキュメントを複製できるようにします。

コードは2つのファイルに分けて構成します:

  • Document.java: クローニングをサポートするドキュメントを表すクラスを作成します。Document は3つの private フィールドを持ちます:title (String)、author (String)、version (int)。すべてのフィールドを初期化するコンストラクタと、それぞれのゲッターメソッドを含めてください。また、バージョン番号を更新するための setVersion(int version) メソッドも追加してください。

    Document クラスに Cloneable インターフェースを実装させ、clone() メソッドをオーバーライドして Document を返すようにします。メソッド内では CloneNotSupportedExceptionRuntimeException でラップして処理してください。

    toString() をオーバーライドして、Document[title=X, author=Y, version=Z] を返すようにします。ここで X、Y、Z は実際のフィールド値です。

  • Main.java: ドキュメントを作成してクローンすることで、Document クラスを実際に動かしてみましょう。3つの入力(タイトル (String)、著者 (String)、バージョン番号 (int))を受け取ります。

    これらの値を使用してオリジナルの Document を作成し、それをクローンしてコピーを作成します。クローン作成後、setVersion() を使用してコピーのバージョンを 1 増やして変更します。これにより、クローンがオリジナルから真に独立していることが示されます。

    次の3行を出力してください:

    1. Original: に続けて、オリジナルドキュメントの toString() の内容
    2. Clone: に続けて、クローンされたドキュメントの toString() の内容
    3. Independent: に続けて、オリジナルとクローンが異なるオブジェクトであるかどうかを示す true または false!= 比較を使用)

3つの入力(ドキュメントのタイトル (String)、著者名 (String)、バージョン番号 (int))を受け取ります。

クローンのバージョンを変更した後も、オリジナルのドキュメントが変更されないことに注目してください。これは clone() が真に独立したコピーを作成したことを証明しています!

チートシート

clone()メソッドはオブジェクトのコピーを作成します。これを使用するには、クラスがCloneableインターフェースを実装し、Objectクラスのclone()メソッドをオーバーライドする必要があります:

public class Person implements Cloneable {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public Person clone() {
        try {
            return (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

独立したコピーの作成:

Person original = new Person("Alice", 25);
Person copy = original.clone();
// copyは同じ値を持つ別のオブジェクトです

デフォルトでは、clone()シャローコピー(浅いコピー)を実行し、プリミティブ値と参照をコピーします。オブジェクトがフィールドとして他のオブジェクトを含んでいる場合、オリジナルとクローンの両方が同じネストされたオブジェクトを参照します。ネストされたオブジェクトを含む真に独立したコピーを作成するには、clone()メソッド内でそれらのネストされたオブジェクトもクローンすることで、ディープコピー(深いコピー)を実装してください。

自分で試してみよう

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 入力を読み込む
        String title = scanner.nextLine();
        String author = scanner.nextLine();
        int version = scanner.nextInt();
        
        // TODO: 入力値を使用してオリジナルのDocumentを作成する
        
        // TODO: オリジナルのドキュメントをクローンしてコピーを作成する
        
        // TODO: クローンのバージョンを1増やして修正する
        
        // TODO: "Original: " に続いてオリジナルのドキュメントを出力する
        
        // TODO: "Clone: " に続いてクローンされたドキュメントを出力する
        
        // TODO: "Independent: " に続いて true/false を出力する (オリジナル != クローン であるかを確認)
        
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン