Java serialization and duplicate objects

前端 未结 1 329
抹茶落季
抹茶落季 2020-12-15 23:15

I have the following setup:

public class A {
  private Set cSet;
}

public class B {
  private Set cSet;
}

public class C {}
相关标签:
1条回答
  • 2020-12-15 23:51

    No, you won't get more instances of C than necessary. That's because internally, the ObjectOutputStream registers every ever serialized object in a 'handle table'. So even across multiple invocations of writeObject(Object), the same object will never be written twice!

    API documentation for ObjectOutputStream:

    (...) Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written. (...)

    Consider this code (assuming A, B and C are Serializable and both, A and B have a non-transient field c pointing to an instance of C):

    A a = new A();
    B b = new B();
    C c = new C();
    a.c = c;
    b.c = c;
    
    out.writeObject(a); // writes a and c
    out.writeObject(b); // writes b and the handle to c
    

    Now let's read both objects:

    A a2 = (A)in.readObject(); // reads a and c
    B b2 = (B)in.readObject(); // reads b and handle to c, so b.c points to existing c
    // now this is true: a2.c == b2.c
    

    This also works if you directly write an object twice, e.g.:

    A a = new A();
    out.writeObject(a); // writes a
    out.writeObject(a); // writes handle to a
    

    The second writeObject will only write the handle, not the object itself. That means when you deserialize the objects again, you won't get two instances of A:

    A a1 = (A)in.readObject(); // reads a
    A a2 = (A)in.readObject(); // reads the handle and returns existing a
    // now this is true: a1 == a2
    

    By calling reset, you can clear the 'handle table' so that the stream behaves like newly created.

    Note that a ObjectOutputStream also offers a method writeObjectUnshared(Object) that always writes an object as a new unique object to the stream.

    0 讨论(0)
提交回复
热议问题