Подтвердить что ты не робот

Когда мне нужно изменить serialVersionUID?

Я знаю, что я могу использовать serialVersionUID для управления версией классов. И я читал, что я могу добавлять или удалять поля, и класс будет по-прежнему совместим, он просто будет использовать значения по умолчанию.

Когда должен менять serialVersionUID?

4b9b3361

Ответ 1

Значение поля serialVersionUID в идеале должно быть изменено, если в структуру класса вносятся несовместимые изменения. Полный список несовместимых изменений указан в Спецификация сериализации объектов Java.

Для дальнейшего расширения несовместимые изменения в классе будут препятствовать созданию механизма десериализации для создания экземпляра объекта, поскольку в потоке есть информация, которая не соответствует текущему определению класса.

Ответ 2

Часто повторяющаяся мантра об изменении serialVersionUID каждый раз, когда вы меняете класс, является полной и полной бессмыслицей. См. эта статья Sun, которую они переиздали на своем сайте и которая была перенесена в технологическую сеть Oracle после приобретения.

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

Во всех остальных случаях вы должны испортить свой котел, пытаясь использовать пользовательские методы readObject()/writeObject() и/или writeReplace()/readResolve() и/или serialFields аннотации, чтобы вы могли продолжать читать объекты из существующих сериализаций. Как только вы нарушите то, что у вас есть серьезная головная боль, действительно кошмар.

Ответ 3

Если вы не указываете поле serialVersionUID в своих классах Serializable, компилятор Java будет указывать один для вас - по существу, это хэш имени класса, имен интерфейса, методов и полей класса, Однако методы могут быть изменены в любое время, поэтому, если вам нужно изменить способ десериализации сохраненного класса, вы можете переопределить метод readObject. Если вы укажете поле serialVersionUID в своем коде, однако, компилятор не будет переопределять это, даже если вы делаете несовместимые изменения, что может привести к исключению во время выполнения - ваша среда IDE или компилятор не будет дайте вам предупреждение. (EDIT - thanks EJP). IDE, такие как Eclipse, могут вставлять для вас UID компилятора, если вы хотите легко проверить, как компилятор просматривает определенные изменения.

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

Одно предостережение, я лично испытал боль, которая работает с классами Serializable, первоначально предназначенными для долгосрочного хранения, которые были неправильно разработаны. Например, хранение элементов GUI на диске, а не создание их при необходимости. Спросите себя, действительно ли Serializable лучший способ сохранить ваши данные.

Ответ 4

Для полноты приведем список изменений, которые нарушают совместимость сериализации Java в соответствии со спецификацией java 8:

  • Удаление полей
  • Перемещение классов вверх или вниз по иерархии
  • Изменение нестатического поля на статическое или непереходное поле на переходное
  • Изменение объявленного типа примитивного поля
  • Измените метод writeObject или readObject, чтобы он больше не записывал и не считывал данные поля по умолчанию, или изменял их так, чтобы он пытался записать или прочитать их, когда предыдущая версия этого не делала.
  • Изменение класса с Serializable на Externalizable или наоборот
  • Изменение класса с типа enum на тип enum или наоборот
  • Удаление Serializable или Externalizable
  • Добавление метода writeReplace или readResolve в класс

Ответ 5

Вы можете установить serialiVersionUID на то же значение для жизни класса. (Не всегда хорошая идея). Примечание: вы можете реализовать свою собственную стратегию проверки версий сериализации с помощью readObject/writeObject, если вам это нужно, и оставить UID без изменений.

Единственный раз, когда вы ДОЛЖНЫ его изменить, - если вы уже сериализовали некоторые данные в файл и хотите его прочитать. Если он по какой-либо причине изменился, вы ДОЛЖНЫ установить serialiVersionUID в версию в файле, чтобы иметь какую-либо надежду на возможность чтения данных.