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

Почему не генерируется serialVersionUID?

Почему не генерируется serialVersionUID? Я столкнулся с проблемой на сервере приложений, где, по-видимому, был кэширован старый класс.

4b9b3361

Ответ 1

serialversionuid не генерируется автоматически, потому что это опасно. Когда serialversionuid установлен, это означает, что две версии класса совместимы с сериализацией.

Представьте, что у вас есть класс под названием Foo, и он имеет no serialversionuid (по умолчанию), и вы сериализуете экземпляр Foo в файл. Позже вы добавите новых членов в класс Foo. Если вы попытаетесь десериализовать объект Foo из файла, вы получите отказ от сериализации, указав, что объекты несовместимы. Они несовместимы, это то, что вы хотите и по умолчанию. Они несовместимы, потому что новые члены класса Foo не могут быть инициализированы из старого сериализованного экземпляра Foo.

Теперь вы можете сказать: "Мне все равно, в моем приложении приемлемо, чтобы эти поля были неинициализированы". Если это действительно так, вы можете установить serialversionuid нового класса Foo таким же, как старый класс Foo. Это скажет Java, что объекты совместимы с сериализованностью, а Java не будет жаловаться при десериализации старого экземпляра Foo в новый класс Foo (но новые поля по-прежнему будут неинициализированы).

Если вы создаете новый класс в первый раз, и вы устанавливаете serialversionuid, вводите контракт. Этот контракт гласит: "Для всех будущих версий этого класса с одним и тем же serialversionuid я гарантирую, что они совместимы с состоянием и сериализацией".

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

Ответ 2

Он автоматически создается на основе структуры класса. Если структура изменяется, идентификатор регенерируется (в соответствии с спецификацией сериализации это hashof класс).

Итак, вам лучше определить явный serialVersionUID.

Ответ 3

Если вы используете Eclipse в качестве своей IDE, вы можете щелкнуть правой кнопкой мыши предупреждение о пропавшем serialVersionUID, и вы получите два варианта:

1) Определите значение Eclipse по умолчанию, которое имеет значение 1L; или
2) Определите случайное генерируемое длинное значение

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

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

На практике я обнаружил, что даже если вы начинаете с идентичного исходного кода на двух или более машинах (например, из Subversion), где serialVersionUID был undefined в классе, генерируемое компилятором значение в класс отличается на каждой машине, когда код компилируется. Это может вызвать запутывающие ошибки во время разработки.

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

http://download-llnw.oracle.com/javase/6/docs/api/java/io/Serializable.html