Private static final long serialversionuid in java

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

Java-университет

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

Serialization и SerialVersionUID всегда остается загадкой для многих Java-разработчиков. Я часто вижу вопросы насчет того что такое SerialVersionUID , или что произойдет, если я не объявлю SerialVersionUID в моем Serializable -классе? Помимо запутанного и редкого использования, есть еще одна причина для этого вопроса — это предупреждение Eclipse IDE об отсутствии SerialVersionUID , например: «The Serializable class Customer does not declare a static final SerialVersionUID field of type long» (» Serializable -класс Customer не объявил статическое финальное поле SerialVersionUID типа long»). В этой статье, вы сможете не только узнать основы Java SerialVersionUID но и его влияние на процесс сериализации и де-сериализации. Когда вы объявляете класс, как Serializable путем реализации интерфейса-маркера java.io.Serializable , среда выполнения Java сохраняет экземпляр этого класса на диске с помощью механизма сериализации по умолчанию, если вы не настроили процесс использования интерфейса Externalizable. Во время сериализации, среда выполнения Java создает номер версии для класса, так что она может десереализировать его позже. В Java этот номер версии известен как SerialVersionUID . Если во время десериализации, SerialVersionUID не соответствует, то процесс завершится с исключением InvalidClassException в потоке » main » java.io.InvalidClassException , а также напечатает имя класса и соответствующий SerialVersionUID . Быстрое решение для исправления этой проблемы – скопировать SerialVersionUID и определить его как константу типа private static final long в вашем классе. В этой статье мы узнаем, о том, почему мы должны использовать SerialVersionUID в Java и как использовать инструмент serialver JDK для генерации этого ID. Если вы новичок в сериализации, вы также можете посмотреть Топ 10 вопросов о сериализации Java на интервью чтобы оценить свои знания и найти пробелы в вашем понимании для дальнейшего чтения. Подобно Concurrency (параллельности) и Multi-threading (многопоточности), Serialization (сериализация) это уже другая тема, которая заслуживает чтения несколько раз.

Читайте также:  Not empty selector css

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

Как я сказал, когда мы не определилили значение SerialVersionUID как static final long в нашем классе, механизм сериализации сделает это за нас. Этот механизм чувствителен ко многим деталям, включая поля вашего класса, их модификаторы доступа, интерфейсы, которые он реализует и даже различные реализации компилятора, любые изменения в классе или использование другого компилятора может дать результат иного SerialVersionUID , который в конечном итоге остановит перезагрузку сериализованных данных.Очень рискованно полагаться на механизм сериализации Java для генерации этого id, вот почему рекомендуется явно определять SerialVersionUID в вашем Serializable-классе. Я настоятельно советую прочитать классику Java — Joshua Bloch “Effective Java” для понимания сериализации Java и проблем неправильной их обработки. Кстати, JDK также предоставляет инструмент serialver , который расположен в директории bin каталога JAVA_HOME, на моем компьютере C:\Program Files\Java\jdk1.6.0_26\bin\serialver.exe, который может быть использован для генерирования SerialVersionUID для старых классов. Это очень полезно в случае, если вы внесли изменения в ваш класс, который нарушает сериализацию и ваше приложение не может перезагрузить сериализированные экземпляры. Вы легко можете использовать эту утилиту для создания SerialVersionUID для старых экземпляров, а затем использовать его в явном виде объявив поле как private static final long SerialVersionUID . Кстати, очень рекомендуется из соображений производительности и безопасности использовать обычный двоичный формат для сериализации, опять же “Effective Java” имеет несколько параграфов, которые демонстрируют преимущества обычного формата в мельчайших деталях.

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

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

 $ 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 , это откроет инспектор serial version , который принимает полное имя класса и показывает его Serial version .

Читайте также:  Не открываются гиперссылки html

Резюме

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

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

  1. SerialVersionUID используется для указании версии сериализованных данных.
  2. Когда мы не объявляем SerialVersionUID в нашем классе, среда выполнения Java делает это за нас, но этот процесс чувствителен ко многим метаданным класса включая количество полей, тип полей, модификаторы доступа полей, интерфейсов, которые реализованы в классе и пр. Вы можете найти точную информацию в документации о сериализации от Oracle.
  3. Рекомендуется объявлять SerialVersionUID как private static final long переменную во избежание механизма по умолчанию. Некоторые IDE, такие как Eclipse, также выдают предупреждения если вы забыли это, например: «The Serializable class Customer does not declare a static final SerialVersionUID field of type long» («Serializable-класс Customer не объявил статическое финальное поле SerialVersionUID типа long»). Хотя вы и можете отключить это предупреждение следуя в Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems, я предлагаю не делать этого. Только когда восстановление данных не требуется я могу быть небрежным в этом. Вот как эта ошибка выглядит в Eclipse IDE, все что вам нужно это принять первое быстрое решение.
  4. Вы также можете использовать утилиту serialver из JDK для генерирования Serial Version для классов в Java. Утилита также имеет GUI, который включается при передаче параметра – show .
  5. Лучшая практика в сериализации – это явно объявить SerialVersionUID , чтобы избежать любых проблем при де-сериализации, особенно если вы работаете с клиент-серверным приложением, которое опирается на сериализованные данные, например, RMI.

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

  • Difference between transient and volatile variable in Java
  • Difference between Serializable and Externalizable interface in Java
  • When to use transient variable in Java

Оригинал здесь

Источник

SerialVersionUID in Java

The serialization at runtime associates with each serializable class a version number called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. Geek, now you must be wondering why do we use SerialVersionUID?

It is because SerialVersionUID is used to ensure that during deserialization the same class (that was used during serialize process) is loaded. Consider ran the illustration given below to get a fairer understanding of Serialization & Deserialization.

Illustration:

  • Suppose a person who is in the UK and another person who is in India, are going to perform serialization and deserialization respectively. In this case, to authenticate that the receiver who is in India is the authenticated person, JVM creates a unique ID which is known as SerialVersionUID.
  • In most cases, serialization and deserialization both activities are done by a single person with the same system and same location. But in serialization, sender and receiver are not the same people that is the persons may be different, machine or system may be different and location must be different then SerialVersionUID comes into the picture. In serialization, both sender and receiver should have .class file at the time of beginning only i.e. the person who is going to do serialization and the person who is ready for deserialization should contain the same .class file at the beginning time only.

Serialization at the time of serialization, with every object sender side JVM will save a Unique Identifier. JVM is responsible to generate that unique ID based on the corresponding .class file which is present in the sender system.
Deserialization at the time of deserialization, receiver side JVM will compare the unique ID associated with the Object with local class Unique ID i.e. JVM will also create a Unique ID based on the corresponding .class file which is present in the receiver system. If both unique ID matched then only deserialization will be performed. Otherwise, we will get Runtime Exception saying InvalidClassException. This unique Identifier is nothing but SerialVersionUID.

There are also certain problem associations depending on the default SerialVersionUID generated by JVM as listed below:

  1. Both sender and receiver should use the same JVM with respect to platform and version also. Otherwise, the receiver is unable to deserialize because of different SerialVersionUID.
  2. Both sender and receiver should use the same ‘.class’ file version. After serialization, if there is any change in the ‘.class’ file at the receiver side then the receiver is unable to deserialize.
  3. To generate SerialVersionUID internally JVM may use complex algorithms which may create performance problems.

Implementation:

We can solve the above problem by configuring our own SerialVersionUID. We can configure our own SerialVersionUID for which we need 3 classes as follows:

  • Random class which contains two variables which are going to Serialize, let it be ‘Geeks’
  • Class for sender side which is going to Serialize an object
  • Class for receiver side which is going to deserialize
private static final long SerialVersionUID=10l;

Источник

Оцените статью