クライアント/サーバープログラムがあり、ObjectOutputStream
経由writeObject()
してオブジェクトを送信していますreadObject()
。
私が送信しているオブジェクトは、いくつかのフィールドと内部の別のオブジェクトで構成されるクラスです(外部オブジェクトWrapper
と内部オブジェクトを呼び出しましょうInner
。両方のカスタムオブジェクトはを実装しserializable
ます。
初めて送信するときはWrapper
、すべてが問題なく機能します。両方に格納されているすべてのものWrapper
、Inner
およびすべてのフィールドは、問題なくシリアル化および逆シリアル化されます。
ただし、クライアントが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
クラス(以前と同じインスタンス)をDIFFERENT文字列(つまり、最初の文字以外の文字を含む)で変更します。
inner.setValue("newValue");
out.writeObject(new Wrapper(inner));
ただし、inner.getValue()
サーバー上でを見ると、変更されておらず、まだに等しい"value"
です。
送信する前に、内部クラスのハードコピーを作成することで、これを解決しました。
Inner newInner = new Inner();
newInner.setValue("newValue");
out.writeObject(new Wrapper(newInner));
新しい値が更新されます。
シリアル化がこのように機能するのはなぜですか?