web-dev-qa-db-ja.com

Java:super.clone()を呼び出すclone()操作

クラスのclone()メソッドでsuper.clone()を返すという考えを完全には理解していません。まず、スーパークラスは「ではない」サブクラスですが、サブクラスは「である」スーパークラスであるため、要求されたものよりも少ないデータを含むスーパークラスであるオブジェクトを返すこととは関係ありませんか。そして、サブクラスの長いチェーンがあり、それぞれがsuper.clone()を呼び出しているのに、なぜそれがサブクラスではないチェーンのルートで最終的にObject.clone()を呼び出さないのですか?

紛らわしい場合は申し訳ありません。時々混乱する

42
TurtleToes

Objectclone()の実装は、実際のクラスがCloneableを実装しているかどうかを確認し、その実際のクラスのインスタンスを作成します。

したがって、クラスを複製可能にする場合は、Cloneableおよびdowncastsuper.clone()の結果をクラスに実装する必要があります。もう1つの負担は、super.clone()の呼び出しが、発生しないことがわかっていても、キャッチする必要があるCloneNotSupportedExceptionをスローできることです(クラスがCloneableを実装しているため) 。

CloneableインターフェースとcloneクラスのObjectメソッドは、オブジェクト指向設計が間違っている明らかなケースです。

53
Laurent Pireyn

これを考慮してください:継承するクラスのチェーンがあります。それぞれに独自の変数がある場合とない場合があります。参照を複製する等号演算子(==)とは対照的に、クローンが行うことは、新しい参照を持つオブジェクトの複製されたコピーです。上記の例では、チェーンの最後のオブジェクトを複製します。最後のオブジェクトはスーパークラスで構成されており、それぞれが異なる複製メソッドの実装を持っている可能性があるため、独自のオブジェクトを複製する前に、最初に複製された親オブジェクトを受け取るためにcloneのスーパークラス実装を呼び出すことは非常に理にかなっています。

通常、クローニングに関連する別の用語は、浅くて深いクローニングです。シャロークローンはオブジェクトの正確なレプリカの作成を指しますが、ディープクローンはオブジェクトのレプリカと元のオブジェクトが参照するすべての子オブジェクトを作成します。

このリンク でのクローン作成の詳細

5
Assaf Adato

javadoc of Object.clone() を注意深く読んでください。オブジェクトのコピーが返されます。コピーは、クローンが呼び出されるオブジェクトのインスタンスと同じクラスの別のインスタンスです。つまりfoo.clone().getClass() == foo.getClass()

5
JB Nizet