141

クローンメソッドとJavaのコピーコンストラクタ。どちらが正しい解決策です。それぞれのケースをどこで使用しますか?

4

6 に答える 6

116

クローンは壊れているので、使用しないでください。

Object クラスの CLONE METHOD は、純粋な Java メソッドでは不可能なことを実行する、やや魔法のようなメソッドです。つまり、そのオブジェクトの同一のコピーを生成します。これは、Java コンパイラー* のベータ版リリースの頃から、初期の Object スーパークラスに存在していました。そして、すべての古代の魔法と同様に、呪文が予期せず逆火するのを防ぐために適切な呪文を必要とします

オブジェクトをコピーする方法を好む

Foo copyFoo (Foo foo){
  Foo f = new Foo();
  //for all properties in FOo
  f.set(foo.get());
  return f;
}

続きを読む http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

于 2010-03-11T19:19:24.553 に答える
55

clone()そのままでは機能しないことに注意してください。で作成するメソッドを実装Cloneableしてオーバーライドする必要があります。clone()public

clone()(他の回答で述べたように、この方法には多くの設計上の問題があるため) 好ましいいくつかの代替案があり、コピー コンストラクターには手作業が必要です。

  • BeanUtils.cloneBean(original)によって作成されたもののような浅いクローンを作成しObject.clone()ます。(このクラスはcommons-beanutilsからのものです)

  • SerializationUtils.clone(original)ディープ クローンを作成します。(つまり、最初のレベルだけでなく、プロパティ グラフ全体が複製されます) ( commons-langから)、すべてのクラスは実装する必要がありますSerializable

  • Java Deep Cloning Libraryは、実装を必要とせずにディープ クローニングを提供します。Serializable

于 2010-03-11T19:22:43.880 に答える
34

clone()はいくつかの間違いを伴って設計されているため(この質問を参照)、回避するのが最善です。

効果的なJava2ndEdition、アイテム11から:クローンを慎重にオーバーライドする

Cloneableに関連するすべての問題を考えると、他のインターフェースはそれを拡張すべきではなく、継承用に設計されたクラス(項目17)はそれを実装すべきではないと言っても過言ではありません。その多くの欠点のために、一部のエキスパートプログラマーは、クローンメソッドをオーバーライドせず、おそらく配列をコピーする場合を除いて、それを呼び出さないことを選択します。継承用のクラスを設計する場合、正常に動作する保護されたクローンメソッドを提供しないことを選択した場合、サブクラスがCloneableを実装することは不可能になることに注意してください。

この本では、コピーコンストラクターがクローン可能/クローンよりも優れている多くの利点についても説明しています。

  • リスクが発生しやすい言語外オブジェクト作成メカニズムに依存していません
  • 彼らは、薄く文書化された慣習への強制力のない遵守を要求しません
  • 最終フィールドの適切な使用と競合しません
  • 不要なチェック例外をスローしません
  • キャストは必要ありません。

すべての標準コレクションにはコピーコンストラクターがあります。それらを使用してください。

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
于 2012-04-10T15:19:44.947 に答える
19

コピー コンストラクターは、クラス タイプをコピー コンストラクターのクラス タイプに制限することに注意してください。例を考えてみましょう:

// Need to clone person, which is type Person
Person clone = new Person(person);

personのサブクラスである可能性があるPerson場合 (またはPersonインターフェースである場合)、これは機能しません。これがクローンの要点であり、実行時に適切なタイプを動的にクローンできることです (クローンが適切に実装されていると仮定します)。

Person clone = (Person)person.clone();

また

Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer

現在、適切に実装されていると仮定するpersonと、どのようなタイプでもかまいません。Personclone

于 2011-02-17T07:13:34.133 に答える
3

参照: clone メソッドを適切にオーバーライドするには? . Java ではクローン作成が機能していないため、正しく行うのは非常に困難です。正しく行ったとしても、実際にはあまり提供されないため、手間をかける価値はありません。

于 2010-03-11T19:48:35.780 に答える