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() は浅いコピー(shallow copy)を実行します。これは、プリミティブ値と参照をコピーすることを意味します。オブジェクトがフィールドとして他のオブジェクトを含んでいる場合、オリジナルとクローンの両方が同じネストされたオブジェクトを参照することになります。ネストされたオブジェクトを含む完全に独立したコピーを作成するには、clone() メソッド内でそれらのネストされたオブジェクトもクローンすることで、深いコピー(deep copy)を実装する必要があります。
チャレンジ
簡単オブジェクトのクローニングを実演するドキュメント管理システムを構築しましょう。独立したコピーを作成するためにクローン可能な Document クラスを作成し、オリジナルをそのまま保持しながらドキュメントを複製できるようにします。
コードは2つのファイルに分けて構成します:
Document.java: クローニングをサポートするドキュメントを表すクラスを作成します。Document は3つの private フィールドを持ちます:title(String)、author(String)、version(int)。すべてのフィールドを初期化するコンストラクタと、それぞれのゲッターメソッドを含めてください。また、バージョン番号を更新するためのsetVersion(int version)メソッドを追加してください。Document クラスに
Cloneableインターフェースを実装させ、clone()メソッドをオーバーライドしてDocumentを返すようにします。メソッド内ではCloneNotSupportedExceptionをRuntimeExceptionでラップして処理してください。toString()をオーバーライドして、Document[title=X, author=Y, version=Z]を返すようにします。ここで X、Y、Z は実際のフィールド値です。Main.java: ドキュメントを作成してクローンすることで、Document クラスを実際に動かしてみましょう。3つの入力(タイトル (String)、著者 (String)、バージョン番号 (int))を受け取ります。これらの値を使用してオリジナルの Document を作成し、それをクローンしてコピーを作成します。クローン作成後、
setVersion()を使用してコピーのバージョンを1増やして修正します。これにより、クローンがオリジナルから真に独立していることが示されます。次の3行を出力してください:
Original:に続いてオリジナルのドキュメントの toString()Clone:に続いてクローンされたドキュメントの toString()Independent:に続いて、オリジナルとクローンが異なるオブジェクトであるかどうかを示すtrueまたはfalse(!=比較を使用)
ドキュメントのタイトル (String)、著者名 (String)、バージョン番号 (int) の3つの入力を受け取ります。
クローンのバージョンを変更した後も、オリジナルのドキュメントが変更されないことに注目してください。これは 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: クローンの version を1増やして修正する
// TODO: "Original: " に続いてオリジナルのドキュメントを出力する
// TODO: "Clone: " に続いてクローンされたドキュメントを出力する
// TODO: "Independent: " に続いて true/false を出力する (original != clone かどうかを確認する)
}
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造7特殊メソッドとObjectクラス
toString() メソッドequals() と hashCode()clone() メソッドcompareTo() と ComparableComparator インターフェースまとめ - カスタムソート