Отправка того же, но измененного объекта через ObjectOutputStream
-
02-07-2019 - |
Вопрос
У меня есть следующий код, который показывает либо ошибку, либо недоразумение с моей стороны.
Я отправил тот же список, но измененный через ObjectOutputStream.Один раз как [0], а другой как [1].Но когда я читаю это, я получаю [0] дважды.Я думаю, это вызвано тем фактом, что я отправляю один и тот же объект, и 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); } }
Решение
Поток имеет ссылочный график, поэтому объект, отправленный дважды, не даст двух объектов на другом конце, вы получите только один.И отправка одного и того же объекта дважды по отдельности даст вам один и тот же экземпляр дважды (каждый с одинаковыми данными - это то, что вы видите).
Смотрите метод reset(), если вы хотите сбросить график.
Другие советы
Макс правильный, но вы также можете использовать:
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);
В противном случае один и тот же объект будет сброшен дважды, когда поток будет закрыт или закончится его буфер.
Просто К вашему сведению, когда вы десериализуете объекты в, скажем o1
и o2
, o1 != o2
.