特别在readUnshared()
方法ObjectInputStream
, 的背景下什么是“回参考”意味着什么?什么是Java中的后向引用?
我横跨术语在此
来到如果readUnshared被称为反序列化反向参考(先前已写入流的对象的流表示),一个ObjectStreamException将抛出。
编号:https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#readUnshared()
特别在readUnshared()
方法ObjectInputStream
, 的背景下什么是“回参考”意味着什么?什么是Java中的后向引用?
我横跨术语在此
来到如果readUnshared被称为反序列化反向参考(先前已写入流的对象的流表示),一个ObjectStreamException将抛出。
编号:https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#readUnshared()
当您使用ObjectOutputStream
序列化对象时,流将'记住'它已写入的对象。当它必须再次写入相同的对象时,它不会再写入整个对象,而是写入一个称为“后退引用”的标识符。
接收方ObjectInputStream
也将跟踪接收到的对象,并在读取后退引用时返回它先前读取的同一对象。
如在answer by CoronA中所述,这是用于序列化彼此指向的对象,还用于确保在序列化到另一个JVM时保留一个JVM中的身份相等性。
方法readUnshared
(及其计数器部分writeUnshared
)用于摆脱此行为:它确保读取(写入)的对象将是唯一的(并且不会作为反向引用重用)。这是相当先进的,我不记得曾经见过或曾经使用它,但是再次,我很少看到序列化的用法。
考虑:
class A {
B b;
}
class B {
String s;
A a;
}
及以下建筑:
A a = new A();
a.b = new B();
b.a = a;
如果这样的递归结构是序列化和反序列化应该是功能上是相同的。 b.a
不应该是A
的任意实例,而应该是引用b的那个实例。
在这种情况下,b.a
是反向引用,因为A会在ObjectInputStream
的B之前被读取。
反向引用是对先前已写入/读取到流中的同一对象的引用。把它想象成一个指向流中前一个对象的指针。
反向引用很有用,因为如果它在同一个流中被多次(反)序列化,并且在反序列化时还允许引用相等,它们将极大地减少对象的占用空间。
使用反向引用:
Object obj = new Object();
obj == obj // true
writeObject(obj);
writeObject(obj);
Object obj1 = readObject();
Object obj2 = readObject();
obj1 == obj2 // true
如果我们不使用反向引用,最后的声明将是false
。
这不是什么回参考指的。它与循环引用无关,尽管它们将大大受益于后向引用。 – 4castle
使用'writeUnshared'序列化一个像这样的循环结构会抛出一个'StackOverflowException'。 – 4castle
从我的角度来看,有几种情况需要反向引用。循环引用是其中的一部分。是的 - writeUnshared可能会失败,但在我写这个答案的时候,没有人提到readUnshared。 – CoronA