Why isn't the serialVersionUID automatically generated?

Why isn't the serialVersionUID automatically generated? I was running into an issue on an application server where apparently an old class was being cached.

10
задан palacsint 8 July 2012 в 21:03
поделиться

3 ответа

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

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

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

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

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

22
ответ дан 3 December 2019 в 14:33
поделиться

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

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

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

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

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

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

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

2
ответ дан 3 December 2019 в 14:33
поделиться

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

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

9
ответ дан 3 December 2019 в 14:33
поделиться
Другие вопросы по тегам:

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