Вопрос-ответ

What is a serialVersionUID and why should I use it?

Что такое serialVersionUID и почему я должен его использовать?

Eclipse выдает предупреждения, когда serialVersionUID отсутствует.


Сериализуемый класс Foo не объявляет статическое конечное поле serialVersionUID типа long


Что такое serialVersionUID и почему это важно? Пожалуйста, покажите пример, отсутствие которого serialVersionUID вызовет проблему.

Переведено автоматически
Ответ 1

Документы для java.io.Serializable, вероятно, являются самым хорошим объяснением, которое вы получите:


Среда выполнения сериализации связывает с каждым сериализуемым классом номер версии, называемый serialVersionUID, который используется во время десериализации для проверки того, что отправитель и получатель сериализованного объекта загрузили классы для этого объекта, совместимые с точки зрения сериализации. Если получатель загрузил класс для объекта, который отличается serialVersionUID от класса соответствующего отправителя, то десериализация приведет к InvalidClassException. Сериализуемый класс может объявить свой собственный serialVersionUID явно, объявив поле с именем serialVersionUID, которое должно быть статическим, конечным и иметь тип long:



ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;


Если сериализуемый класс явно не объявляет serialVersionUID, то среда выполнения сериализации вычислит значение по умолчанию serialVersionUID для этого класса на основе различных аспектов класса, как описано в спецификации сериализации объектов Java (TM) . Однако настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляли serialVersionUID значения, поскольку вычисления по умолчанию serialVersionUID очень чувствительны к деталям класса, которые могут варьироваться в зависимости от реализаций компилятора, и, таким образом, могут привести к непредвиденным InvalidClassExceptions результатам во время десериализации. Следовательно, чтобы гарантировать согласованное serialVersionUID значение в различных реализациях компилятора java, сериализуемый класс должен объявлять явное serialVersionUID значение. Также настоятельно рекомендуется, чтобы в явных serialVersionUID объявлениях по возможности использовался модификатор private, поскольку такие объявления применяются только к непосредственно объявляемому классу — serialVersionUID поля не являются полезными в качестве наследуемых членов.


Ответ 2

Если вы сериализуете только потому, что вам нужно сериализовать ради реализации (какая разница, сериализуете ли вы для HTTPSession, например ... сохранен он или нет, вам, вероятно, все равно, de-serializing объект формы), то вы можете это проигнорировать.

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

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

Ответ 3

Я не могу упустить эту возможность, чтобы дополнить книгу Джоша Блоха "Эффективная Java" (2-е издание). Глава 10 - незаменимый ресурс по сериализации Java.

Согласно Josh, автоматически сгенерированный UID генерируется на основе имени класса, реализованных интерфейсов и всех общедоступных и защищенных членов. Изменение любого из них любым способом изменит serialVersionUID. Таким образом, вам не нужно возиться с ними, только если вы уверены, что не более одной версии класса когда-либо будут сериализованы (либо между процессами, либо извлечены из хранилища позже).

Если вы пока игнорируете их, а позже обнаружите, что вам нужно каким-то образом изменить класс, но сохранить совместимость со старой версией класса, вы можете использовать инструмент JDK serialver для генерации serialVersionUID в старом классе и явно установить это в новом классе. (В зависимости от внесенных изменений вам может потребоваться также реализовать пользовательскую сериализацию, добавив методы writeObject и readObject - см. Serializable javadoc или вышеупомянутую главу 10.)

Ответ 4

Вы можете сказать Eclipse игнорировать эти предупреждения serialVersionUID:


Окно> Настройки> Java> Компилятор> Ошибки / предупреждения> Потенциальные проблемы программирования


На случай, если вы не знали, в этом разделе есть множество других предупреждений, которые вы можете включить (или даже сообщить о некоторых как об ошибках), многие из них очень полезны:


  • Потенциальные проблемы программирования: возможно случайное логическое присвоение

  • Потенциальные проблемы программирования: доступ к нулевому указателю

  • Ненужный код: локальная переменная никогда не читается

  • Ненужный код: избыточная проверка null

  • Ненужный код: ненужное приведение или 'instanceof'

и многое другое.

java serialization