2012-04-29 2 views
1

Предположим, у меня есть объекты типа A, B и C. У меня есть 3 Карты, которые содержат все экземпляры A, B и C соответственно. Внутри, как A, так и B имеют Карты C. Я хочу иметь возможность хранить и восстанавливать состояние приложения в любое время.Сериализация связанных объектов в java

Итак, до сегодняшнего дня у меня всегда были сериализованные пирамидальные приложения, где я бы назвал сериализацию в верхнем объекте, и вызов будет распространяться на все остальное. Как я могу справиться с этой ситуацией? Если я вызову сериализацию на карте A, а затем на карте B, не будут ли экземпляры C дважды сохраняться? Даже если они это сделают, будет ли десериализация оставить состояние приложения, поскольку это было просто перезапись экземпляров C, когда я десериализую карту B после десериализации карты A?

Заранее спасибо.

ответ

4

Механизм сериализации Java знает о нескольких ссылках на один и тот же объект и не будет дублировать их. Объект будет сохранен один раз, и все внутренние ссылки будут сохранены.

После десериализации ваши объекты будут находиться в одном состоянии: только один экземпляр и несколько ссылок на этот объект.

+0

Как я должен это сделать, то, как писать карты А и В в то же OutputStream? Что произойдет, если я напишу их в разные потоки (файлы в моем случае) один за другим и восстановит их в том же (или другом) порядке? – bluehallu

+0

Поместите их в один объект и сериализуйте этот объект, возможно, самый простой способ сделать это. –

1

Лучшее, что нужно сделать, это вернуться к вашей модели, подобной «пирамиде», путем хранения ваших карт в одном объекте и сериализации этого объекта;

Механизм сериализации обрабатывает графики и несколько экземпляров одного и того же объекта без каких-либо проблем.

+0

Проблема в том, что я не могу поставить A и B на одно и то же место, я знаю, что это сделало бы намного проще :) – bluehallu

3

Javadoc из ObjectOutputStream writes:

Метод writeObject используется для записи объекта в потоке. Любой объект, включая строки и массивы, записывается с помощью writeObject. В поток могут быть записаны несколько объектов или примитивов. Объекты должны быть считаны из соответствующего объекта ObjectInput с теми же типами и в том же порядке, в котором они были записаны.

и

Ссылки на другие объекты (за исключением переходных или статических полей) вызывают те объекты, которые будут написаны также. Несколько ссылок на один объект кодируются с использованием механизма обмена ссылками, так что графики объектов могут быть восстановлены в том же виде, что и при написании оригинала.

В частности, если один и тот же объект записывается повторно в ObjectOutputStream, его данные записываются только один раз.

Вы можете проверить это, запустив следующую программу:

class A implements Serializable { 
    C c; 
} 

class B implements Serializable { 
    C c; 
} 

class C implements Serializable { 

} 

public class Test { 

    public static void main(String[] args) throws Exception { 
     C c = new C(); 

     A a = new A(); 
     a.c = c; 

     B b = new B(); 
     b.c = c; 


     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
      oos.writeObject(a); 
      oos.writeObject(b); 
      oos.writeObject(c); 
     } 
     byte[] data = baos.toByteArray(); 

     try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) { 
      A newA = (A) ois.readObject(); 
      B newB = (B) ois.readObject(); 
      C newC = (C) ois.readObject(); 

      System.out.println(newA.c == newC && newB.c == newC); // prints "true" 
     } 
    } 
} 
+0

Итак, он работает с одним выходным потоком. Теперь, если я сериализую карту в файл, а B - в другой файл, а затем восстанавливаю их оба? – bluehallu

Смежные вопросы