请参考ObjectOutputStream.reset
。
重置将忽略已写入流的任何对象的状态。状态将重置为与新的ObjectOutputStream
相同。流中的当前点被标记为重置,因此相应的ObjectInputStream
也将在相同点重置。以前写入流的对象不会被视为已经在流中。它们将再次写入流。
output.reset();
output.writeObject(...);
在将同一对象写入序列化之前,请调用reset以确保其更新状态被序列化。否则,它将仅使用对先前写入的具有过时状态的对象的后向引用。
或者,您可以按以下方式使用 ObjectOutputStream.writeUnshared
。
将一个“未共享”的对象写入
ObjectOutputStream
。该方法与
writeObject
相同,只是它总是将给定对象作为流中的新唯一对象写入(而不是指向先前序列化实例的后向引用)。
具体来说:
通过writeUnshared写入的对象始终以与新出现的对象(尚未写入流的对象)相同的方式进行序列化,无论该对象是否已经被先前写入。
如果使用
writeObject
写入了先前使用
writeUnshared
写入的对象,则先前的writeUnshared操作将被视为对单独对象的写入。换句话说,
ObjectOutputStream
永远不会生成对由调用
writeUnshared
写入的对象数据的后向引用。
通过
writeUnshared
编写对象本身并不能保证在反序列化时获得唯一引用,但它允许在流中多次定义单个对象,因此接收者对
readUnshared
的多次调用不会发生冲突。请注意,上述规则仅适用于使用
writeUnshared
编写的基本级别对象,而不适用于要序列化的对象图中任何传递引用的子对象。
output.writeUnshared(...);
请注意,最好将此与
ObjectInputStream.readUnshared
相结合使用。
从
ObjectInputStream
中读取一个“未共享”的对象。此方法与readObject相同,不同之处在于它防止随后调用readObject和readUnshared返回通过此调用获得的反序列化实例的其他引用。
具体而言:
- 如果调用readUnshared来反序列化回溯引用(先前已写入流的对象的流表示形式),则会抛出ObjectStreamException。
- 如果readUnshared成功返回,则任何后续尝试将回溯引用反序列化到由readUnshared处理的流句柄将导致抛出ObjectStreamException。
通过readUnshared反序列化对象会使与返回对象关联的流句柄无效。请注意,这本身并不总是保证readUnshared返回的引用是唯一的;反序列化对象可能定义了一个readResolve方法,该方法返回对其他方可见的对象,或者readUnshared可能返回可以在流中的其他位置或通过外部手段获得的Class对象或枚举常量。如果反序列化对象定义了一个readResolve方法,并且该方法的调用返回一个数组,则readUnshared返回该数组的浅克隆;这保证了返回的数组对象是唯一的,并且即使底层数据流已被操作,也不能从ObjectInputStream上的readObject或readUnshared调用中第二次获取该数组对象。
obj = input.readUnshared();