Сериализованный класс Java, сохраненный в файл — как я могу обеспечить обратную совместимость?

Я написал приложение для Android для создания и сохранения контрактов «Фотоуслуги» на устройство в виде файла для последующей печати. Класс в значительной степени состоит из целых чисел, двойных чисел и строк (включая подписи base64_encoded).

Класс реализует сериализуемый. Тем не менее, я беспокоюсь о том, что обновлю приложение, забуду не редактировать класс и не отредактировать его, перезагрузить на свое устройство и сохранить X контрактов в файл, а затем не смогу их получить.

Раньше я просматривал и нашел serialVersionUID. В сообщении я прочитал, что просто реализуя это простое длинное значение, если я обновлю класс, его все равно можно будет прочитать. Это правильно? Я прочитал документацию по Java для Serializable и не смог принять решение о том, каков результат реализации serialVersionUID.

Может ли кто-нибудь помочь пролить свет на это для меня? Достаточно простого ответа «да, это будет работать или нет, это не будет работать», и любые ссылки, которые помогут мне научиться, будут еще лучше!


person wilson208    schedule 09.08.2013    source источник
comment
Краткий ответ: вы не можете. Это не то, как сериализация работает в Java (или на самом деле то, для чего она предназначалась). Вы, вероятно, захотите использовать JSON или какую-либо другую схему/библиотеку сериализации, которая является более динамичной и щадящей.   -  person Brian Roach    schedule 10.08.2013
comment
Связано: stackoverflow.com/q/6374646/1065197   -  person Luiggi Mendoza    schedule 10.08.2013
comment
Используйте другой механизм, если обратная совместимость абсолютно критична.   -  person Louis Wasserman    schedule 10.08.2013
comment
Короткий ответ: вы можете, но вам нужно очень внимательно прочитать главу «Управление версиями» Спецификации сериализации объектов и оставаться в этих границах со своими изменениями.   -  person user207421    schedule 10.08.2013


Ответы (1)


Чтобы получить обратную совместимость с сериализацией, вы должны

  1. Имейте один и тот же serialVersionUID для класса, который вы хотите сериализовать во всех своих версиях.
  2. Вы можете добавлять/удалять методы класса по своему усмотрению, и это не повлияет на сериализацию.
  3. Вы можете добавить сколько угодно новых участников, и они будут иметь значение по умолчанию своего типа сразу после того, как пользователь обновит приложение до новой версии.

Пример:

// Old format
class FileFormat implements Serializable {
   static final long serialVersionUID = 44L;

   public String member1;
}

...
// New format
class FileFormat implements Serializable {
   static final long serialVersionUID = 44L;

   public String member1;
   public int member2;
}

В приведенном выше примере в первый раз, когда пользователь будет читать файл, сериализованный со старым FileFormat, с новым приложением, он/она получит объект FileFormat нового формата с member2, установленным на 0. (Строки/Объекты будут нулевыми, числа с плавающей запятой будут равны 0,0. f, удваивает 0,0 и т. д.).

  1. Вы не можете удалить какое-либо поле из класса (вы потеряете обратную совместимость)
  2. Вы не можете изменить иерархию класса в средствах перемещения класса вверх или вниз

Есть много других ограничений, ознакомьтесь с официальным документом: http://docs.oracle.com/javase/6/docs/platform/serialization/spec/version.html

person Lake    schedule 11.08.2013