Статьи

Зачем использовать SerialVersionUID внутри класса Serializable в Java

Serialization и SerialVersionUID всегда остаются загадкой для многих разработчиков Java. Я часто вижу такие вопросы, как этот SerialVersionUID или что произойдет, если я не объявлю SerialVersionUID в своем классе Serializable? Помимо сложности и редкого использования, еще одной причиной этих вопросов является предупреждение Eclipse IDE об отсутствии SerialVersionUID, например «Класс Serializable Customer не объявляет статическое конечное поле SerialVersionUID типа long» . В этой статье вы познакомитесь не только с основами Java SerialVersionUID, но и с его эффектами в процессе сериализации и десериализации. Когда вы объявляете класс как Serializable, реализуя интерфейс маркера java.io.Serializable, среда выполнения Java сохраняет экземпляр этого класса на диск с использованием механизма сериализации по умолчанию, при условии, что вы не настроили процесс с использованием интерфейса Externalizable . Во время сериализации среда выполнения Java создает номер версии для класса, чтобы он мог десериализовать его позже. Этот номер версии известен как SerialVersionUID в Java. Если во время десериализации SerialVersionUID не совпадает, процесс завершится с ошибкой InvalidClassException в качестве исключения в потоке «main» java.io.InvalidClassException , а также напечатает имя класса и соответствующий SerialVersionUID. Быстрое решение этой проблемы — копирование SerialVersionUID и объявление их как частной статической конечной длинной константы в вашем классе. В этой статье мы узнаем о том, почему мы должны использовать SerialVersionUID в Java, и как использовать инструмент JDK serialver для генерации этого идентификатора. Если вы новичок в сериализации, вы также можете увидеть Топ 10 интервью по сериализации Java, чтобы оценить свои знания и найти пробел в своем понимании для дальнейшего чтения. Как и в случае параллелизма и многопоточности, сериализация — это еще одна тема, заслуживающая пару прочтений.

Зачем использовать SerialVersionUID в Java

Как я уже сказал, когда мы не объявляем SerialVersionUID как статическое, конечное и длинное значение в нашем классе, механизм Serialization создает его для нас. Этот механизм чувствителен ко многим деталям, включая поля в вашем классе, их модификатор доступа, интерфейс, который они реализуют, и даже различные реализации компилятора, любые изменения в классе или использование другого компилятора могут привести к различному SerialVersionUID , который многие в конечном итоге прекратят перезагружать сериализованные данные. Слишком рискованно полагаться на механизм сериализации Java для генерации этого идентификатора, и поэтому рекомендуется объявить явный SerialVersionUID в вашем классе Serializable . Я настоятельно рекомендую прочитать классический заголовок Java Джошуа Блоха «Эффективная Java», чтобы понять сериализацию Java и проблемы неправильной обработки. Кстати, JDK также предоставляет инструмент под названием serialver, расположенный в каталоге bin папки JAVA_HOME , на моей машине C: \ Program Files \ Java \ jdk1.6.0_26 \ bin \ serialver.exe, который можно использовать для генерации SerialVersionUID для старых классы. Это очень полезно, если вы внесли изменения в ваш класс, что нарушает сериализацию и ваше приложение не может перезагрузить сериализованные экземпляры. Вы можете просто использовать этот инструмент для создания SerialVersionUID для старых экземпляров, а затем явно использовать его в своем классе, объявив личное , статическое , окончательное и длинное поле SerialVersionUID. Между прочим, настоятельно рекомендуется, как из-за производительности, так и по соображениям безопасности, использовать настраиваемый двоичный формат для сериализации, еще раз в Effective Java есть пара элементов, которые подробно объясняют преимущества пользовательского формата.

Как использовать инструмент serialver JDK для генерации SerialVersionUID

Вы можете использовать инструмент serialver JDK для генерации SerialVersionUID для классов. Это особенно полезно для развивающихся классов, оно возвращает SerialVersionUID в формате, который легко скопировать. Вы можете использовать инструмент serialver JDK, как показано в примере ниже:

1
2
3
4
5
6
7
8
$ serialver
use: serialver [-classpath classpath] [-show] [classname...]
 
$ serialver -classpath . Hello
Class Hello is not Serializable.
 
$ serialver -classpath . Hello
Hello:    static final long SerialVersionUID = -4862926644813433707L;

Вы даже можете использовать инструмент serialver в форме GUI, выполнив команду $ serialver -show, при этом откроется инспектор серийной версии, который принимает полное имя класса и показывает его серийную версию.

Резюме

Теперь мы знаем, что такое SerialVersionUID и почему важно объявить его в классе Serializable, пришло время пересмотреть некоторые важные факты, связанные с Java SerialVersionUID.

  1. SerialVersionUID используется для версии сериализованных данных. Десериализовать класс можно только в том случае, если его SerialVersionUID совпадает с сериализованным экземпляром.
  2. Когда мы не объявляем SerialVersionUID в нашем классе, среда выполнения Java генерирует его для нас, но этот процесс чувствителен ко многим метаданным класса, включая количество полей, тип полей, модификатор доступа к полям, интерфейс, реализованный классом и т. Д. Вы можете найти точную информацию в документации по сериализации от Oracle.
  3. Рекомендуется объявить SerialVersionUID как частную статическую переменную final long, чтобы избежать механизма по умолчанию. Некоторые IDE, такие как Eclipse, также отображают предупреждение, если вы пропустите его, например, «Класс Serializable Customer не объявляет статическое окончательное поле SerialVersionUID типа long» . Хотя вы можете отключить эти предупреждения, перейдя в «Окно»> «Установки»> «Java»> «Компилятор»> «Ошибки / предупреждения»> «Потенциальные проблемы программирования», я предлагаю не делать этого. Единственный случай, который я вижу, является небрежным, когда восстановление данных не требуется. Вот как эта ошибка выглядит в Eclipse IDE, все, что вам нужно сделать, это принять первое быстрое исправление.
  4. Что такое SerialVersionUID в Java и зачем вам это нужно

  5. Вы даже можете использовать инструмент serialver из JDK для генерации последовательной версии для классов в Java. Он также имеет графический интерфейс, который можно включить, передав параметр -show.
  6. В Java рекомендуется сериализовать явное объявление SerialVersionUID, чтобы избежать проблем во время десериализации, особенно если вы запускаете приложение клиент-сервер, которое использует сериализованные данные, например RMI.

Это все о SerialVersionUID в Java . Теперь мы знаем, почему важно объявить SerialVersionUID прямо в классе. Вы можете поблагодарить вашу IDE за это напоминание, которое может нарушить десериализацию вашего класса.

Если вы хотите узнать больше о сериализации и связанной с ней концепции, вы также можете увидеть эти удивительные статьи: