2

私は ASF の寄稿者によって書かれた記事を読んでいました。彼は、オブジェクトをディープ クローンするための "古い Java トリック" は、オブジェクトをシリアライズしてからデシリアライズして別のオブジェクトに戻すことであると簡単に述べました。これを読んだとき、私は一時停止し、「これはかなり賢い」と思いました。残念ながら、ディープ クローニングもシリアル化もこの記事の主題ではなかったため、著者は自分が話していることの例を示したことはありません。

私は、次のようなものについて話していると仮定する必要があります。

public class Dog implements Serializable
{
    // ...

    public Dog deepClone()
    {
        Dog dogClone = null;
        try
        {
            FileOutputStream fout = new FileOutputStream("mydog.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(this);
            oos.close();

            FileInputStream fin = new FileInputStream("mydog.dat");
            ObjectInputStream ois = new ObjectInputStream(fin);
            dogClone = (Dog)ois.readObject();
            ois.close();

            return dogClone;
        }
        catch(Exception e)
        { 
            // Blah
        }
    }

私が少しずれている可能性がある場合 (プラスまたはマイナスの数行のコード)、これはオブジェクトのディープ クローンを作成するための一般的に受け入れられている方法ですか? この方法に落とし穴や注意点はありますか?

対処されていない同期/並行性/スレッドセーフの問題はありますか?

これがオブジェクトのディープ クローン作成のベスト プラクティスである場合、私はそれを宗教的に使用するつもりです。

4

1 に答える 1

2

これは、deep-clonging の一般的な方法の 1 つです。欠点は次のとおりです。

  1. 一般に、シリアライゼーション/デシリアライゼーションを行うのは遅いです。カスタム複製はより高速です。

  2. 明らかに、シリアライズ可能なオブジェクトのみを複製します

  3. 何を連載しているのかわかりにくい。あなたの犬がより大きな構造物(犬の群れ)への上向きのポインターを持っている場合、注意を払わないと、犬のクローンを作成すると、他の100匹の犬のクローンが作成される可能性があります. Dog の手動クローンは、パック参照を単純に無視し、同じプロパティを持つ新しい個々の犬オブジェクトを作成し、おそらく同じ犬のパックを参照します、パックのクローンは作成しません。

スレッド セーフは、手動クローンの実行と同じです。ほとんどの場合、プロパティはシリアライザーによってソース オブジェクトから順次読み取られます。スレッド セーフに注意しないと、複製中に部分的に変更された犬を複製する可能性があります。

したがって、これを常に使用することはおそらくお勧めできません。非常に単純なオブジェクトの場合、単純な手動クローン/コピー コンストラクターを作成するのは簡単で、パフォーマンスが大幅に向上します。また、複雑なオブジェクト グラフの場合、意図しないものを複製するリスクが生じることがあります。そのため、便利ですが、注意して使用する必要があります。

ところで、あなたの例では、ファイル ストリームではなくメモリ ストリームを使用します。

于 2011-09-24T22:12:17.693 に答える