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

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

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

48
задан Gray 14 December 2017 в 17:55
поделиться

4 ответа

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

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

52
ответ дан 26 November 2019 в 18:53
поделиться

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

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

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

4
ответ дан 26 November 2019 в 18:53
поделиться

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

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

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

22
ответ дан 26 November 2019 в 18:53
поделиться

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

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

-1
ответ дан 26 November 2019 в 18:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: