[???] / [Java FAQ] / [S027]
S027: オブジェクトのコピー - clone

[S027 Q-01]
Back
オブジェクトのコピーは dst = src ではいけないのでしょうか? [S027 A-01] だめですね。 上記の操作によって値がコピーされるのはプリミティブ型(primitive)のみ です。 Java では、以下のような2つの異なるタイプが提供されています。 ・プリミティブ(ビルトイン)型 ・参照(オブジェクト)型 プリミティブ型には以下のものがあります。 boolean, char, byte, short, int, long, float, double Java では通常のオブジェクトは上記参照型として定義されます。 すなわち、オブジェクトを格納する変数は全て実体ではなく参照を保持 しているということです。 プリミティブタイプの代入操作では、元の値が代入先に転記されますので 完全な意味でのコピー操作となります。 参照タイプの代入操作も、変数の値自体は完全にコピーされますがその意味する 所は参照のコピーとなりますので、それぞれの変数が指し示すオブジェクトの 実体は同一のものとなります。 上記操作後においても dst 及び src は単に同一のオブジェクトを指し示す 異なった変数となるだけですので、一方に対する操作は、もう一方にも反映 されることになります。
[S027 Q-02]
Back
オブジェクトをコピーしたいのですが? [S027 A-02] Object#clone() メソッドを使用します。
[S027 Q-03]
Back
オブジェクトのコピー時に CloneNotSupportedException が発生するのですが? [S027 A-03] コピー元のオブジェクトが Cloneable インターフェースを実装していない からです。 特定のオブジェクトに対して clone() メソッドによるコピーを行う必要が ある場合は、対象となるオブジェクトに java.lang.Cloneable を実装しな ければなりません。
[S027 Q-04]
Back
コピー元のオブジェクトを変更すると、コピー先のオブジェクトも変更され てしまいます。なぜ? [S027 A-04] clone() メソッドによるコピーでは、内部に保持されているオブジェクトは 複製されないためです。 たとえば、 class Sample implements Cloneable { StringBuffer buffer; } このようなクラスにおいては buffer 変数は、StringBuffer のインスタンス の参照を保持する器となります。 Sample.clone() によって複製されるインスタンスが保持する buffer 変数は コピー元と同一な値を持ちますから、同じ StringBuffer のインスタンスへ の参照となります。 したがって、コピー元の buffer に対する変更は、コピー先の buffer にも 反映されるように見えるのです。 @see System#arraycopy
[S027 Q-05]
Back
オブジェクトを内部に含まれるオブジェクトまで完全に複製したいのですが? [S027 A-05] clone() メソッドを再実装して実現します。 実装の詳細は、対象とするオブジェクトの構造に依存するため一般的な方法 はありません。 オブジェクトが java.lang.Serializable インターフェースを実装している 場合は、ObjectOutputStream ObjectInputStream を用いることで完全な複製 を作成することもできます。 以下 targetObject を複製して copyObject に取得する際のサンプルコード です。(例外処理は除く) ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(targetObject); ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream(bos.toByteArray())); copyObject = bis.readObject();

Back
contributor: Osamu Hasegawa, Tsuyoshi Tsuhtan Sato
コメントの送り先 Java FAQ BBS