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

对象的Java部分(反)序列化,java,serialization,deserialization,binary-serialization,Java,Serialization,Deserialization,Binary Serialization,假设我们有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); 之后,我们希望将它们序

假设我们有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);
之后,我们希望将它们序列化存储在一个文件中。 如果我们对baz进行反序列化,只修改onlyFoo并再次将baz反序列化到该文件中,则该栏仍然包含原始onlyFoo,因此onlyFoo有两个不同的版本

相反,我想要的是,我存储theBaz和theBar而不存储仅限oo,分别存储这三个对象,一旦有人反序列化theBaz,我也只想给他一个oo。如果他再次反序列化更改的onlyFoo,baz工具栏将具有相同的modified onlyFoo,因此如果有人请求一个对象(例如theBar),他将获得包含所有引用对象(onlyFoo)的完整序列化对象,就像正常序列化过程将返回的那样

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

更新

  • 我不能修改这些类
  • 我不知道所有的课程。它应该适用于我可能从未听说过的所有可序列化对象(它们可能是最终的,也可能不是最终的)

  • 标记不希望用transient关键字序列化的引用。

    您可以如下所示制作
    foo
    transient

    class bar {
        transient foo f;
        int i;
    }
    

    如果需要更多控制,可以覆盖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 
    

    你说得对,但我不能改变foo、bar或baz的定义。其思想是,它适用于所有可序列化的对象。因此,您必须手动将引用设置为null。如果您想要通用解决方案,可以使用java.reflectionHm完成,如果我获得另一个指向该对象的指针并将字段设置为null,我可以稍后反序列化第一个对象,并在反序列化第一个对象后将第二个对象设置为字段。谢谢,这应该可以工作。还有其他选择吗?我希望我的方法的调用方也能获得完整的序列化对象,我不想在反序列化之后直接序列化它来存档。没错,但正如另一条评论中提到的,我无法修改这些类。该类是否为扩展打开?我的意思是它是否是最终的?更新了问题:“我不知道所有的课程。它应该适用于所有我可能从来没有听说过的可序列化对象。“我看,如果它们是最终的,可能是个大问题,所以请考虑接受(检查标记)其中一个AbSWrHSM,我不能修改类本身,但我可以把它们包成代理。该代理将以某种方式重写writeObject,即它们序列化为其创建的对象,而不是自身。然后我简单地序列化代理。他们需要使用反射,但我看到的问题是,它应该适用于所有可序列化对象,即使我从未听说过它们。我将此标记为正确答案,因为它对我帮助很大。我正在创建一个工作原型,完成后我会在这里发布/链接。完全忘记我的原型: