Java śledzi obiekty, które zostały zapisane w strumieniu, a kolejne wystąpienia są zapisywane jako identyfikator, a nie rzeczywisty obiekt serializowany.
Na przykład, jeśli napiszesz instancję „a” do strumienia, strumień nadaje temu obiektowi unikalny identyfikator (powiedzmy „1”). W ramach serializacji „a” musisz serializować „b”, a strumień nadaje mu kolejny identyfikator („2”). Jeśli następnie napiszesz „b” do strumienia, jedyną zapisaną rzeczą jest identyfikator, a nie rzeczywisty obiekt.
Strumień wejściowy robi to samo w odwrotnym kierunku: dla każdego obiektu, który czyta ze strumienia, przypisuje numer identyfikacyjny przy użyciu tego samego algorytmu co strumień wyjściowy, a ten numer identyfikuje instancję obiektu na mapie. Kiedy widzi obiekt, który został zserializowany przy użyciu identyfikatora, pobiera oryginalne wystąpienie z mapy.
Tak opisują to dokumenty API :
Wiele odwołań do jednego obiektu jest kodowanych za pomocą mechanizmu współdzielenia odniesień, dzięki czemu wykresy obiektów można przywrócić do tego samego kształtu, jak w momencie pisania oryginału
Takie zachowanie może powodować problemy: ponieważ strumień zawiera twarde odwołanie do każdego obiektu (aby wiedział, kiedy zastąpić identyfikator), możesz zabraknąć pamięci, jeśli napiszesz do niego wiele obiektów przejściowych. Rozwiązujesz to, dzwoniąc reset()
.
W Javie rozwiązuje się to poprzez buforowanie zserializowanych obiektów i zapisywanie ich uchwytu, gdy jest on ponownie zapisywany.
Zobacz krok 5 w http://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html .
źródło