1. ホーム
  2. java

[解決済み] clone() vs copy コンストラクタ vs ファクトリメソッド?

2023-07-13 12:22:26

質問

Javaでclone()の実装についてググってみたところ http://www.javapractices.com/topic/TopicAction.do?Id=71

以下のようなコメントがついています。

コピーコンストラクタと静的ファクトリメソッドはcloneの代替手段を提供し、実装がより簡単になります。

私がしたいことは深いコピーを作ることだけです。 clone()を実装することは非常に理にかなっているように思えますが、このGoogleランキング上位の記事を見ると、少し怖くなりますね。

以下、気がついた問題点です。

コピーコンストラクタは Generics では動作しません。

以下はコンパイルできない擬似コードです。

public class MyClass<T>{
   ..
   public void copyData(T data){
       T copy=new T(data);//This isn't going to work.    
   }
   ..
}

サンプル1:ジェネリッククラスでコピーコンストラクタを使用する。

ファクトリーメソッドには標準的な名前がありません。

再利用可能なコードのためのインターフェイスを持つことは非常に素晴らしいことです。

public class MyClass<T>{
    ..
    public void copyData(T data){
        T copy=data.clone();//Throws an exception if the input was not cloneable
    }
    ..
}

サンプル2:汎用クラスでclone()を使用する。

cloneは静的メソッドではないことに気づきましたが、それでもすべてのprotectedフィールドのディープコピーを作成する必要があるのではないでしょうか? clone()を実装する場合、クローン不可能なサブクラスで例外を投げる余分な労力は私には些細なことに思えます。

私は何かを見逃しているのでしょうか? どんな洞察も感謝されます。

どのように解決するのですか?

基本的には のクローンが壊れています。 . ジェネリックで簡単に動くものはないでしょう。もし、このようなものがあれば(ポイントを押さえるために短縮しています)。

public class SomeClass<T extends Copyable> {


    public T copy(T object) {
        return (T) object.copy();
    }
}

interface Copyable {
    Copyable copy();
}

それから、コンパイラの警告で、仕事を終わらせることができます。ジェネリックは実行時に消去されるため、コピーを行うものはコンパイラ警告でキャストが生成されることになります。 この場合は回避できない。 . いくつかのケースでは回避可能ですが(kb304さん、ありがとうございます)、すべてではありません。インターフェイスを実装するサブクラスまたは未知のクラスをサポートしなければならない場合 (必ずしも同じクラスを生成しないコピー可能なコレクションを反復していた場合など) を考えてみてください。