Java对象的局部(反)序列化

3

假设我们有三个类:

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

现在我们创建实例。
foo onlyFoo = new foo("the only one");
bar theBar = new bar(onlyFoo, 123);
baz theBaz = new baz(onlyFoo);

接下来,我们希望将它们序列化并存储在一个文件中。如果我们反序列化theBaz,仅修改onlyFoo并再次将theBaz反序列化到文件中,theBar仍然包含原始的onlyFoo,因此存在两个不同版本的onlyFoo。

相反,我希望将theBaz和theBar不包括onlyFoo,将这三个对象分别存储,并且一旦有人反序列化theBaz,我想要给他onlyFoo。如果他再次反序列化更改后的onlyFoo,则theBaztheBar将具有相同的修改后的onlyFoo,因此如果有人请求一个对象(例如theBar),他将获得带有所有引用对象(onlyFoo)的完整序列化对象,就像正常的序列化过程所返回的那样。

我知道我必须手动和分别存储对象并保持引用,因为默认的序列化无法处理这个问题。我不知道的是如何部分序列化/反序列化Java对象?我需要将基元及其包装器与“更高级”的对象分开并单独存储。

更新

  1. 我不能修改这些类。
  2. 我不知道所有的类。它应该适用于我从未听说过的所有可序列化的对象(它们可能是final或不是

这个类可以扩展吗?我的意思是它是final的还是不是? - Narendra Pathai
更新了问题:“我不知道所有的类。它应该适用于所有可序列化的对象,即使我从未听说过。” 我明白了,如果它们是final类型,这也可能是一个大问题。 - user1563700
请考虑接受(勾选)其中一个答案。 - AlexWien
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


嗯,我无法修改类本身,但我可以将它们包装成代理。这些代理将以一种重写writeObject的方式进行序列化,以便它们序列化为它们所代表的对象而不是它们自己。然后我只需序列化代理即可。他们需要使用反射来实现,但我看到的问题是,它应该适用于所有可序列化的对象,即使我从未听说过它们。 - user1563700
我将其标记为正确答案,因为它对我帮助很大。我正在创建一个工作原型,完成后我会在这里发布/链接。 - user1563700
彻底忘记我的原型:https://gist.github.com/maklemenz/4515273865853b46fac1 - user1563700

1

使用transient关键字标记您不想序列化的Mark引用。


你说得对,但我不能改变foo,bar或baz的定义。想法是它可以与所有可序列化的对象一起使用。 - user1563700
然后您必须手动将引用设置为null。如果您想要通用解决方案,可以使用java.reflection完成。 - Nemanja
哦,如果我得到另一个指针指向对象并将字段设置为 null,稍后我可以反序列化第一个对象并在第一个对象反序列化后将第二个对象设置到该字段。谢谢,这应该可行。还有其他选项吗?我希望我的方法调用者也能得到完整的序列化对象,并且我不想直接在反序列化后立即序列化它来实现这一点。 - user1563700

0

您可以按照以下方式将foo设置为transient

class bar {
    transient foo f;
    int i;
}

正确地说,但正如另一条评论中提到的,我无法修改这些类。 - user1563700

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接