Ответ 1
Reset будет игнорировать состояние любых объектов, уже записанных в поток. Состояние reset будет таким же, как новый
ObjectOutputStream
. Текущая точка в потоке отмечена как reset, поэтому соответствующийObjectInputStream
будет reset в той же точке. Объекты, ранее записанные в поток, не будут упоминаться как уже находящиеся в потоке. Они снова будут записаны в поток.
/* prevent using back references */
output.reset();
output.writeObject(...);
Вызовите reset перед тем, как написать тот же объект, чтобы обеспечить его обновление состояния. В противном случае он просто будет использовать обратную ссылку на ранее написанный объект с его устаревшим состоянием.
Или вы также можете использовать ObjectOutputStream.writeUnshared
следующим образом.
Записывает объект "unshared" в
ObjectOutputStream
. Этот метод идентиченwriteObject
, за исключением того, что он всегда записывает данный объект в качестве нового уникального объекта в потоке (в отличие от обратной ссылки, указывающей на ранее сериализованный экземпляр).В частности:
Объект, написанный с помощью writeUnshared, всегда сериализуется так же, как вновь появляющийся объект (объект, который еще не был записан в поток), независимо от того, был ли ранее сохранен объект.
Если
writeObject
используется для записи объекта, который ранее был записан с помощью writeUnshared, предыдущая операция writeUnshared обрабатывается так, как если бы это была запись отдельного объекта. Другими словами,ObjectOutputStream
никогда не будет генерировать обратные ссылки на данные объекта, записанные вызовамиwriteUnshared
.При записи объекта через
writeUnshared
сам по себе не гарантирует уникальную ссылку на объект, когда он десериализован, он позволяет определять один объект несколько раз в потоке, так что несколько вызовов наreadUnshared
на приемник не будет конфликтовать. Обратите внимание, что правила, описанные выше, применяются только к объекту базового уровня, написанному с помощьюwriteUnshared
, а не к каким-либо транзитным ссылочным под-объектам в графе объектов, которые должны быть сериализованы.
output.writeUnshared(...);
Обратите внимание, что это хорошая практика, чтобы связать это с ObjectInputStream.readUnshared
.
Считывает объект "unshared" из
ObjectInputStream
. Этот метод идентичен readObject, за исключением того, что он предотвращает последующие вызовыreadObject
иreadUnshared
от возврата дополнительных ссылок на десериализованный экземпляр, полученный с помощью этого вызова.В частности:
- Если
readUnshared
вызывается для десериализации обратной ссылки (представления потока объекта, который был ранее записан в поток),ObjectStreamException
будет выбрано- Если
readUnshared
возвращается успешно, любые последующие попытки десериализации обратных ссылок на дескриптор потока, десериализованныеreadUnshared
, вызовутObjectStreamException
.Удаление десериализации объекта с помощью
readUnshared
отменяет дескриптор потока, связанный с возвращенным объектом. Обратите внимание, что это само по себе не всегда гарантирует, что ссылка, возвращаемаяreadUnshared
, уникальна; десериализованный объект может определить методreadResolve
, который возвращает объект, видимый для других сторон, или readUnshared может возвращать объектClass
или константуenum
, доступную в другом месте потока или через внешние средства. Если десериализованный объект определяет методreadResolve
, и вызов этого метода возвращает массив, тоreadUnshared
возвращает неглубокий клон этого массива; это гарантирует, что возвращаемый объект массива уникален и не может быть получен во второй раз из вызоваreadObject
или readUnshared наObjectInputStream
, даже если манипулировать базовым потоком данных.
obj = input.readUnshared();