【问题标题】:Will Java Serialization produce duplicates? What about the references in serialized instances?Java序列化会产生重复吗?序列化实例中的引用呢?
【发布时间】:2018-09-27 11:39:35
【问题描述】:

Java 序列化会产生重复的实例吗?如果有,是浅复制还是深复制?

我有几个具有以下设置的课程:

public class A{
    public C c;
}

public class B {
    public C c;
}

public class C implements Serializable {
    ...
}

public class Wrapper implements Serializable {
    public C c;
}

我有一个通过字节数组传递对象的组件,一旦序列化过程结束,ObjectOutputStream/ObjectInputStream 就会被关闭。

首先,我将 A.c 序列化并传递给 B.c。 B.c 是 A.c 的复制品吗? 然后,我在 B 中创建了一个包装器类并包装了 B.c。现在,如果我序列化包装器实例,将其传递给 A 并在 A 中反序列化它,那么被包装的 c 将是什么?参考 B.c?还是一个全新的 C 实例?

伪代码:

{
    ...
    A a = new A();
    B b = new B();
    C c = new C();
    a.c = c;
}

{
    //Somewhere in A
    byte[] cData = SomethingThatSerializesObjects.Serialize(c);
    b.c = SomethingThatSerializesObjects.Deserialize(cData);

    //Is b.c a duplication of a.c?
}

{
    //Somewhere in B
    Wrapper wrapper = new Wrapper();
    wrapper.c = c;
    byte[] wrapperData = SomethingThatSerializesObjects.Serialize(wrapper);
    //Give the wrapperData to a
}

{
    //And somewhere in A
    //Receives wrapperData
    Wrapper wrapper = SomethingThatSerializesObjects.Deserialize(wrapperData);
    C tmp = wrapper.c;

    //Is tmp a reference to b.c? Or a new C instance?
}

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    反序列化会产生新的实例:每次反序列化都会得到最初序列化的对象的新副本

    C c1 = SomethingThatSerializesObjects.Deserialize(cData);
    C c2 = SomethingThatSerializesObjects.Deserialize(cData);
    // c1 != c2
    

    readResolve() 方法是解决此问题的一种方法,有一个示例 here

    【讨论】:

    • 谢谢!但是对象内的引用呢?如果我写:Wrapper w1 = SomethingThatSerializesObjects.Deserialize(wrapperData); Wrapper w2 = SomethingThatSerializesObjects.Deserialize(wrapperData); w1.c = w2.c 会怎样?那里有点困惑。
    • 你得到了整个对象图的一个新副本所以w1.c != w2.c
    猜你喜欢
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 2012-04-13
    • 2016-01-08
    • 1970-01-01
    相关资源
    最近更新 更多