簡體   English   中英

在對象序列化流上發送具有不同字段的相同對象

[英]Sending the same objects with different fields over an object serialized stream

我有一個客戶端/服務器程序,我通過writeObject()readObject()通過ObjectOutputStream發送對象。

我發送的對象是由幾個字段組成的類,另一個是內部對象(讓我們調用外部對象Wrapper和內部Inner 。兩個自定義對象都實現了可serializable

我第一次發送Wrapper ,一切都完美無瑕。 存儲在WrapperInner和所有字段中的所有內容都會Wrapper化和反序列化而不會出現問題。

但是,當客戶端然后修改Inner類時,將其放入Wrapper ,並再次發送它,服務器接收的Inner實例與第一次接收的實例相同。

我的客戶:

Inner inner = new Inner();
inner.setValue("value");

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(new Wrapper(inner));

服務器:

ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
Wrapper wrapper = (Wrapper) in.readObject();
String value = wrapper.getInner().getValue();

然后,客戶端使用不同的字符串(即包含其他字母,然后是第一個字符串)修改Inner類(與之前相同的實例):

inner.setValue("newValue");
out.writeObject(new Wrapper(inner));

但是,當我查看服務器上的inner.getValue()時,它沒有更改,仍然等於"value"

我通過制作內部類的硬拷貝,然后發送它來解決這個問題:

Inner newInner = new Inner();
newInner.setValue("newValue");
out.writeObject(new Wrapper(newInner));

現在,新值將按預期更新。

為什么序列化以這種方式工作?

這是ObjectOutputStream的預期行為。 引用Javadocs:

使用引用共享機制對對單個對象的多個引用進行編碼,以便可以將對象圖形恢復為與寫入原始圖像時相同的形狀。

由於您使用相同的內部類引用,它只是通過對先前發送的對象的引用發送。 檢查所有的所有對象的字段,看其中是否已經改變。 我懷疑不僅是inner.getValue()等於所發送的第一對象,但該inner的第二對象由服務器接收的對象是相同的對象== )作為inner從所述第一對象。

如果你打電話:

out.reset();

在使用調整后的inner字段發送對象之前,您的代碼應該可以正常工作。 reset()方法清除引用緩存,這有助於序列化流的高效。 作為旁注,如果要在流中發送大量臨時對象,則reset()尤其必要,因為否則這些對象會緩存在內存中並導致堆耗盡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM