特別在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