特别是在readUnshared()
的{{1}}方法的上下文中,
什么是"反向引用"意思?
我在这个
中遇到了这个词如果调用readUnshared反序列化反向引用(先前已写入流的对象的流表示),则抛出ObjectStreamException。
参考:https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#readUnshared()
答案 0 :(得分:5)
使用ObjectOutputStream
序列化对象时,流将“记住”它已写入的对象。当它必须再次写入同一个对象时,它不会再次写入整个对象,而是会写一个称为“后向引用”的标识符。
接收ObjectInputStream
还将跟踪已收到的对象,并在读取后退引用时返回它之前读取的同一对象。
如answer by CoronA中所述,这是 - 除其他外 - 用于序列化彼此指向的对象,但也确保在序列化到另一个JVM时保留一个JVM中的身份相等。
方法readUnshared
(及其对应部分writeUnshared
)用于摆脱这种行为:它确保读取(写入)的对象是唯一的(并且不作为后向引用重用) )。这是相当先进的,我不记得曾见过或曾经使用过它,但话说回来,我很少看到序列化的用法。
答案 1 :(得分:3)
考虑:
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之前读取。
答案 2 :(得分:1)
反向引用是对先前已写入/读取到流的相同对象的引用。可以把它想象成指向流中前一个对象的指针。
反向引用很有用,因为如果对象在同一个流中被多次(de)序列化,它们会大大减少对象的占用空间,并且在反序列化时也允许引用相等。
使用反向引用:
Object obj = new Object();
obj == obj // true
writeObject(obj);
writeObject(obj);
Object obj1 = readObject();
Object obj2 = readObject();
obj1 == obj2 // true
如果我们没有使用反向引用,则最终语句为false
。