จะเกิดอะไรขึ้นถ้าเราทำให้ซีเรียลไลซ์และดีซีเรียลไลซ์สองวัตถุที่อ้างอิงถึงกันและกัน?


15

เพื่อให้ชัดเจนยิ่งขึ้นนี่เป็นตัวอย่างด่วน:

class A implements Serializable { public B b; }
class B implements Serializable { public A a; }
A a = new A();
B b = new B();
a.b = b;
b.a = a;

แล้วจะเกิดอะไรขึ้นถ้าเราทำให้วัตถุ a และ b เป็นอนุกรมเป็นไฟล์และทำการดีซีเรียลไลซ์ออกจากไฟล์นั้น?

ฉันคิดว่าเราได้วัตถุ 4 ชิ้นชิ้นละ 2 ชิ้น วัตถุที่เหมือนกัน แต่มีอินสแตนซ์ต่างกัน

แต่ฉันไม่แน่ใจว่ามีอะไรอีกหรือมันถูกหรือผิด

หากเทคโนโลยีใดจำเป็นต้องตอบโปรดคิดตาม Java

ขอขอบคุณ.

คำตอบ:


25

Java ติดตามวัตถุที่ถูกเขียนไปยังกระแสข้อมูลและอินสแตนซ์ที่ตามมาจะถูกเขียนเป็น ID ไม่ใช่วัตถุต่อเนื่องที่เกิดขึ้นจริง

ดังนั้นสำหรับตัวอย่างของคุณหากคุณเขียนอินสแตนซ์ "a" ลงในสตรีมสตรีมจะให้ ID นั้นเป็นวัตถุที่ไม่ซ้ำกัน (สมมุติว่า "1") ในฐานะที่เป็นส่วนหนึ่งของการทำให้เป็นอนุกรมของ "a" คุณจะต้องทำให้เป็นอันดับ "b" และสตรีมจะให้ id อื่น ("2") หากคุณเขียน "b" ลงในสตรีมสิ่งเดียวที่เขียนคือ ID ไม่ใช่วัตถุจริง

สตรีมอินพุตทำสิ่งเดียวกันในสิ่งที่ตรงกันข้าม: สำหรับแต่ละวัตถุที่อ่านจากสตรีมนั้นจะกำหนดหมายเลข ID โดยใช้อัลกอริทึมเดียวกับสตรีมเอาต์พุตและหมายเลข ID นั้นจะอ้างอิงอินสแตนซ์ของวัตถุในแผนที่ เมื่อเห็นวัตถุที่ถูกทำให้เป็นอนุกรมโดยใช้ ID มันจะดึงอินสแตนซ์ดั้งเดิมออกจากแผนที่

นี่คือวิธีที่เอกสาร APIอธิบาย:

การอ้างอิงหลายรายการไปยังวัตถุเดียวถูกเข้ารหัสโดยใช้กลไกการแบ่งปันอ้างอิงเพื่อให้กราฟของวัตถุสามารถคืนค่าเป็นรูปร่างเดียวกับเมื่อต้นฉบับถูกเขียน

พฤติกรรมนี้อาจทำให้เกิดปัญหา: เนื่องจากสตรีมมีการอ้างอิงอย่างหนักกับแต่ละวัตถุ (เพื่อให้รู้ว่าเมื่อใดที่จะแทนที่ ID) คุณสามารถเรียกใช้หน่วยความจำไม่เพียงพอหากคุณเขียนวัตถุชั่วคราวจำนวนมากไปยังสตรีม reset()คุณแก้ปัญหาว่าด้วยการโทร


ดังนั้นมันจะทำให้มันกลับสู่สถานะเดิมหลังจากที่ มันเป็นก่อนที่จะเป็นอันดับที่มีการอ้างอิงถึงแต่ละอื่น ๆ ?
Seregwethrin

1
ใช่คุณมีวัตถุ 2 ชิ้นเท่านั้นที่อ้างอิงซึ่งกันและกัน
hectorct

1
ฉันไม่อยากเชื่อเลยว่า Java จะจัดการสิ่งนี้โดยอัตโนมัติ ฉันประทับใจ
Cruncher

2

ใน Java นี้จะแก้ไขได้โดยการแคชวัตถุที่ต่อเนื่องกันและเขียนหมายเลขอ้างอิงของมันเมื่อมันถูกเขียนอีกครั้ง

ดูขั้นตอนที่ 5 ในhttp://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.