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:
Если сериализуемый класс явно не объявляет 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'