2016-09-26 19 views
6

Đặc biệt trong ngữ cảnh của readUnshared() phương thức ObjectInputStream, "tham chiếu ngược" có nghĩa là gì?Tham chiếu ngược trong Java là gì?

Tôi đã xem qua thuật ngữ trong này

Nếu readUnshared được gọi để deserialize một back-tài liệu tham khảo (đại diện dòng của một đối tượng mà đã được viết trước đó vào dòng), một ObjectStreamException sẽ ném.

Ref: https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#readUnshared()

Trả lời

4

Khi bạn tuần tự hóa các đối tượng bằng cách sử dụng ObjectOutputStream, luồng sẽ 'ghi nhớ' đối tượng mà nó đã viết. Khi nó phải viết cùng một đối tượng một lần nữa, nó sẽ không viết toàn bộ đối tượng một lần nữa, thay vào đó nó sẽ viết một định danh được gọi là 'tham chiếu ngược lại'.

Việc nhận ObjectInputStream cũng sẽ theo dõi các đối tượng đã được nhận và sẽ - khi đọc một tham chiếu ngược - trả lại cùng một đối tượng mà nó đọc trước đó.

Như được giải thích trong answer by CoronA, đây là một trong số những thứ khác - được sử dụng để tuần tự hóa các đối tượng trỏ đến nhau, mà còn để đảm bảo bình đẳng danh tính trong một JVM được giữ nguyên khi tuần tự hóa với một JVM khác.

Phương pháp readUnshared (và bộ phận truy cập writeUnshared) được sử dụng để thoát khỏi hành vi này: nó đảm bảo rằng đối tượng đọc (được viết) sẽ là duy nhất (và không được sử dụng lại làm tham chiếu ngược). Điều này là khá tiên tiến và tôi không thể nhớ bao giờ đã thấy hoặc đã sử dụng nó, nhưng sau đó một lần nữa, tôi hiếm khi thấy việc sử dụng serialization ở tất cả.

3

xem xét:

class A { 
    B b; 
} 

class B { 
    String s; 
    A a; 
} 

và sau khi xây dựng:

A a = new A(); 
a.b = new B(); 
b.a = a; 

Nếu một cấu trúc đệ quy như vậy là serialized và deserialized nó nên chức năng giống nhau. b.a không được là một trường hợp tùy ý của A nhưng chính xác là một tham chiếu b.

Trong trường hợp này b.a là backreference, vì A sẽ được đọc trước B trong ObjectInputStream.

+0

Đó không phải là những gì mà tham chiếu ngược đề cập đến.Nó không liên quan gì tới các tham chiếu vòng tròn, mặc dù chúng sẽ được hưởng lợi rất nhiều từ các tham chiếu ngược. – 4castle

+0

Nối tiếp một cấu trúc tròn như thế bằng cách sử dụng 'writeUnshared' sẽ ném một' StackOverflowException'. – 4castle

+1

Theo quan điểm của tôi, có một số tình huống cần có sự phản hồi. Và tham chiếu vòng tròn là một phần của chúng. Có - writeUnshared có thể sẽ thất bại, nhưng tại thời điểm tôi viết câu trả lời này không ai được đề cập readUnshared. – CoronA

1

Tham chiếu ngược là tham chiếu đến đối tượng giống hệt đã được ghi trước đó/đọc cho luồng. Hãy nghĩ về nó như một con trỏ tới một đối tượng trước đó trong luồng. Các tham chiếu ngược rất hữu ích vì chúng làm giảm đáng kể dấu chân của đối tượng nếu nó được (de) tuần tự hóa nhiều lần trong cùng một luồng, và cũng cho phép tham chiếu bình đẳng khi được deserialized.

Sử dụng back-tài liệu tham khảo:

Object obj = new Object(); 
obj == obj // true 
writeObject(obj); 
writeObject(obj); 
Object obj1 = readObject(); 
Object obj2 = readObject(); 
obj1 == obj2 // true 

Nếu chúng ta không sử dụng back-tài liệu tham khảo, báo cáo kết quả cuối cùng sẽ là false.

Các vấn đề liên quan