3

Let's say we have 3 Classes:

class foo { // not a singleton
    String s;
}
class bar {
    foo f;
    int i;
}
class baz {
    foo sameF;
}

Now we create instances

foo onlyFoo = new foo("the only one");
bar theBar = new bar(onlyFoo, 123);
baz theBaz = new baz(onlyFoo);

After that we want to store them serilazed in a file. If we deserialze theBaz, modify onlyFoo and deserialize theBaz to the file again, theBar still contains the original onlyFoo, so there are two different versions of onlyFoo.

What I want instead is that I store theBaz and theBar without onlyFoo, store the three objects separately and once someone deserialize theBaz I want to give him onlyFoo, too. If he deserializes the changed onlyFoo again, theBaz and theBar will have the same modified onlyFoo, so if someone requests an object (for example theBar) he gets the full serialized object with all the referenced objects (onlyFoo) like the normal serialization process would return.

デフォルトのシリアル化ではこの問題を処理できないため、オブジェクトを保存し、参照を手動で個別に保持する必要があることはわかっています。私が知らないのは、Java オブジェクトを部分的にシリアライズ/デシリアライズする方法です。プリミティブとそのラッパーを「より高い」オブジェクトから分離し、このオブジェクトを別々に保存する必要があります。

アップデート

  1. クラスを変更することはできません。
  2. すべてのクラスを知っているわけではありません。おそらく聞いたことのないすべてのシリアライズ可能なオブジェクトで動作するはずです(それらは最終的である場合とそうでない場合があります
4

3 に答える 3

2

より詳細な制御が必要な場合は、writeObject()とreadObject()を上書きして、自分でシリアル化することができます。

class bar {
    ...

    private void writeObject(ObjectOutputStream stream) throws IOException {
      // let version 1, later when you need to have versioning. 
      stream.writeInt(version);
      stream.writeInt(i);
      // leave out 
      // stream.writeObject(foo);

    }
}
// read object the analog, see 

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html#861

于 2012-11-30T18:15:01.170 に答える
1

一時的なキーワードでシリアル化したくない参照をマークします。

于 2012-11-30T17:52:34.920 に答える
0

以下のように作ることができfoo transientます。

class bar {
    transient foo f;
    int i;
}
于 2012-11-30T18:07:44.380 に答える