3

Cloneable修理できないほど壊れていることはよく知られています (詳細については、この質問の説明を参照してください)。

代替案と「どうすれば正しく行うか」に関する最後の質問は、数年前のものです。

そこで、次のように再質問します。

現代(2014年)の代替品はCloneable何ですか?

汎用ソリューションを探しています。次の要件を想像できました。

  • Copyableクラスが実装するある種のインターフェース: A extends Copyable.
  • ディープコピー。Aのインスタンスが のインスタンスを参照する場合、B新しいa.copy()を参照する必要がありますb.copy()
  • 指定されたターゲットにコピーします: a.copyTo(a1)
  • ポリモーフィック コピー: BextendsのA場合、 froma.copyTo(b)のすべてのプロパティをto にコピーする必要があります。Bab

もちろん、これらすべてを自分で実装することはできますが、これには標準インターフェースを用意するのが合理的ではないでしょうか? または、何か不足していますか?


私のコンテキストの背景のビット。私は JAXB とスキーマ派生クラスをよく使用しています。多くの場合、これらのクラスをディープ コピーすると非常に便利です。数年前、私はいくつかの JAXB スキーマ コンパイラ プラグインを作成しcopyToて、上記の要件 (およびそれ以上) を実装するメソッドを生成しました。独自のランタイム API を使用する必要がありました。今、私はケースを再検討していて、標準的な解決策があるかどうかを尋ねることにしました.

4

3 に答える 3

4

私が何度も使用したメカニズムは、シリアライズ/デシリアライズです。もちろん、これはすべてのオブジェクトと要素がシリアライズ可能である場合にのみ機能するため、すべての場合に機能するとは限りません。すべてのオブジェクトがシリアライズ可能である場合、オブジェクトをディープ コピーする非常に効果的な方法です。次のように実行できます。

public class SerializationHelper {
public static byte[] serialize(Object object) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    new ObjectOutputStream(os).writeObject(object);
    return os.toByteArray();
}

@SuppressWarnings("unchecked")
public static <T> T deSerialize(byte[] array) throws IOException, ClassNotFoundException {
    return (T)new ObjectInputStream(new ByteArrayInputStream(array)).readObject();
}

@SuppressWarnings("unchecked")
public static <T> T clone(T object) {
    try {
        return (T)deSerialize(serialize(object));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
于 2014-10-24T09:04:33.533 に答える
2

まず第一に、それCloneableが「壊れている」という人々の意見には同意しません。「壊れた」わけではありません。文書化されていること、つまりObject.clone()例外をスローするかどうかを正確に実行します。人々はそれを好きではありません。なぜなら、それは本来あるべきものではなく、複製可能なオブジェクトのインターフェースであると想定しているからです。

Java (まだ) には、複製可能なオブジェクト用の標準ライブラリーのインターフェースがありません。そのようなインターフェースが追加されればいいのですが、そうではありません。独自のインターフェイスを作成し、独自のクラスにそれを実装させることもできますが、問題は、既存の標準ライブラリ クラスにそれを実装させることができないことです。したがって、独自のクラスのエコシステムのみを扱っている場合にのみ役立ちます。

于 2014-10-25T00:58:13.607 に答える