ObjectOutputStreamを介して同じが変更されたオブジェクトを送信する
-
02-07-2019 - |
質問
バグまたは誤解を示す次のコードがあります。
同じリストを送信しましたが、ObjectOutputStreamで変更しました。 [0]として1回、[1]として1回。しかし、それを読むと、[0]を2回受け取ります。これは、私が同じオブジェクトを介して送信しており、ObjectOutputStreamが何らかの方法でそれらをキャッシュする必要があるという事実が原因だと思います。
これは正常に機能しますか、またはバグを報告する必要がありますか?
import java.io.*; import java.net.*; import java.util.*; public class OOS { public static void main(String[] args) throws Exception { Thread t1 = new Thread(new Runnable() { public void run() { try { ServerSocket ss = new ServerSocket(12344); Socket s= ss.accept(); ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); List same = new ArrayList(); same.add(0); oos.writeObject(same); same.clear(); same.add(1); oos.writeObject(same); } catch(Exception e) { e.printStackTrace(); } } }); t1.start(); Socket s = new Socket("localhost", 12344); ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); // outputs [0] as expected System.out.println(ois.readObject()); // outputs [0], but expected [1] System.out.println(ois.readObject()); System.exit(0); } }
解決
ストリームには参照グラフがあるため、2回送信されたオブジェクトは、もう一方の端に2つのオブジェクトを与えることはなく、1つだけを取得します。そして、同じオブジェクトを別々に2回送信すると、同じインスタンスが2回与えられます(それぞれが同じデータを持ちます。これが表示されています)。
グラフをリセットする場合は、reset()メソッドを参照してください。
他のヒント
Maxは正しいですが、使用することもできます:
public void writeUnshared(Object obj);
警告については以下のコメントを参照
おそらくあなたが望むのは:
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
List same = new ArrayList();
same.add(0);
oos.writeObject(same);
oos.flush(); // flush the stream here
same.clear();
same.add(1);
oos.writeObject(same);
それ以外の場合、ストリームが閉じられるか、バッファがなくなると、同じオブジェクトが2回フラッシュされます。
ご参考までに、オブジェクトをデシリアライズするとき、たとえば o1
と o2
、 o1!= o2
のようにします。
所属していません StackOverflow