Почему serialVersionUID не генерируется автоматически? - PullRequest
10 голосов
/ 25 августа 2010

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

Ответы [ 3 ]

22 голосов
/ 26 августа 2010

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

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

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

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

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

9 голосов
/ 25 августа 2010

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

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

2 голосов
/ 26 августа 2010

Если вы используете 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 / документы / API / Java / IO / Serializable.html

...