SERIALIZATION:

  • To serializean object means to convert its state to a byte stream so that the byte stream can be returned back into a copy of the object.
  • Javaobject is serializable if its class or any of its super classes implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable.

DESERIALIZATION:

  • The reverse process of creating object from sequence of bytes is called deserialization.
  • A class must implement Serializable interface present in java.io package in order to serialize its object successfully.
  • Serializable is a marker interface that adds serializable behavior to the class implementing it.

Uses of serialization and Deserialization in Java:

Serialization and Deserialization in Java. 

  • Serializationis a process of converting an object into a sequence of bytes which can be persisted to a disk or database or can be sent through streams.
  • The reverse process of creating object from sequence of bytes is called deserialization.
[ad type=”banner”]

serialVersionUID: 

  • The serialization 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.
  • The serialVersionUID is used as a version control in a Serializable class.
  • If we do not explicitly declare a serialVersionUID, JVM will do it automatically, based on various aspects of our Serializable class.
  • Defining a serialVersionUID field in serializable class is not mandatory.
  • If a serializable class has an explicit serialVersionUID then this field should be of type long and must be static and final. If there is no serialVersionUID field defined explicitly then serialization runtime will calculate default value for that class. The value can vary based on compiler implementation.
  • It is advised to use private access modifier for serialVersionUID.
  • Different class can have same serialVersionUID.
  • Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is ignored for array classes.
  • If there is a difference between serialVersionUID of loaded receiver class and corresponding sender class then InvalidClassException will be thrown.
  • we should use different serialVersionUID for different version of  same class if we want to forbid serialization of new class with old version of same class.

SerialVersionUID Example

  •  Let start an example to understand how Serializable class use SerialVersionUID to implement version control.

Employee.java

  • A serializable class with a serialVersionUID of 1L.
[pastacode lang=”java” manual=”import%20java.io.Serializable%3B%0A%0Apublic%20class%20Employee%20implements%20Serializable%0A%7B%0A%0A%09%20%20%20private%20static%20final%20long%20serialVersionUID%20%3D%201L%3B%0A%0A%09%20%20%20String%20name%3B%0A%09%20%20%20String%20age%3B%0A%0A%09%20%20%20public%20void%20setName(String%20name)%0A%7B%0A%09%09%20%20%20this.name%20%3D%20name%3B%0A%7D%0Apublic%20void%20setAge(String%20age)%0A%7B%0A%09%09%20%20%20this.age%20%3D%20age%3B%0A%20%7D%0A%0A%09%20%20%20public%20String%20getName()%0A%7B%0A%09%09%20%20%20return%20this.name%3B%0A%20%7D%0A%0A%09%20%20%20public%20String%20getAge()%0A%7B%0A%09%09%20%20%20return%20this.age%3B%0A%20%7D%0A%0A%09%20%20%20%40Override%0A%09%20%20%20public%20String%20toString()%20%0A%7B%0A%20%20%20%20%09%20%20%20return%20new%20StringBuffer(%22%20Name%20%3A%20%22)%0A%20%20%20%20%09%20%20%20.append(this.name)%0A%20%20%20%20%09%20%20%20.append(%22%20Age%20%3A%20%22)%0A%20%20%20%20%09%20%20%20.append(this.age).toString()%3B%0A%20%7D%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/] [ad type=”banner”]

WriteObject.java

  • A simple class to write / serialize the Employee object into a file – “c:\\employee.ser”
[pastacode lang=”java” manual=”import%20java.io.FileOutputStream%3B%0Aimport%20java.io.ObjectOutputStream%3B%0A%0Apublic%20class%20WriteObject%0A%7B%0A%0A%09public%20static%20void%20main%20(String%20args%5B%5D)%20%0A%7B%0A%0A%09%20%20%20Employee%20employee%20%3D%20new%20Employee()%3B%0A%09%20%20%20employee.setName(%E2%80%9CWikitechy%22)%3B%0A%09%20%20%20employee.setAge(%E2%80%9C25%22)%3B%0A%0A%09%20%20%20try%0A%7B%0AFileOutputStream%20fout%20%3D%20new%20FileOutputStream(%22c%3A%5C%5Cemployee.ser%22)%3B%0AObjectOutputStream%20oos%20%3D%20new%20ObjectOutputStream(fout)%3B%0Aoos.writeObject(employee)%3B%0A%09%09oos.close()%3B%0A%09%09System.out.println(%22Done%22)%3B%0A%0A%7Dcatch(Exception%20ex)%0A%7B%0A%09%09%20%20%20ex.printStackTrace()%3B%0A%20%7D%0A%7D%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

ReadObject.java

  • A simple class to read / deserialize the Employee object from file – “c:\\employee.ser”.
[pastacode lang=”java” manual=”import%20java.io.FileInputStream%3B%0Aimport%20java.io.ObjectInputStream%3B%0A%0Apublic%20class%20ReadObject%0A%7B%0Apublic%20static%20void%20main%20(String%20args%5B%5D)%20%7B%0A%0A%09%20%20%20Employee%20employee%3B%0A%0A%20try%0A%7B%0A%0A%09%09%20%20%20FileInputStream%20fin%20%3D%20new%20FileInputStream(%22c%3A%5C%5Cemployee.ser%22)%3B%0A%09%09%20%20%20ObjectInputStream%20ois%20%3D%20new%20ObjectInputStream(fin)%3B%0A%09%09%20%20%20employee%20%3D%20(Employee)%20ois.readObject()%3B%0A%09%09%20%20%20ois.close()%3B%0A%0A%09%09%20%20%20System.out.println(employee)%3B%0A%0A%20%7Dcatch(Exception%20ex)%0A%7B%0A%09%09%20%20%20ex.printStackTrace()%3B%0A%7D%0A%7D%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

Output:

Name : Wikitechy Age : 25

Default serialVersionUID

  •  If no serialVersionUID is declared, JVM will use its own algorithm to generate a default SerialVersionUID.
  • The default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation, and result in an unexpected InvalidClassExceptions during the deserialization process.

How to generate serialVersionUID

  • we can use JDK “serialver” or Eclipse IDE to generate serialVersionUID automatically

Example:

  • It is easy to understand the exact use of the variable.
[pastacode lang=”java” manual=”package%20com.jbt%3B%0A%20%0Aimport%20java.io.Serializable%3B%0A%20%0Apublic%20class%20Employee%20implements%20Serializable%0A%7B%0A%20%20%20public%20String%20firstName%3B%0A%20%20%20public%20String%20lastName%3B%0A%20%20%20private%20static%20final%20long%20serialVersionUID%20%3D%205462223600l%3B%0A%7D%0A%20%0A” message=”java code” highlight=”” provider=”manual”/] [ad type=”banner”]

SerializaitonClass.java (This class will be used to serialize)

[pastacode lang=”java” manual=”package%20com.jbt%3B%0A%20%0Aimport%20java.io.FileOutputStream%3B%0Aimport%20java.io.IOException%3B%0Aimport%20java.io.ObjectOutputStream%3B%0Apublic%20class%20SerializaitonClass%20%7B%0A%20%0A%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%20Employee%20emp%20%3D%20new%20Employee()%3B%0A%20emp.firstName%20%3D%20%22wiki%22%3B%0A%20emp.lastName%20%3D%20%22techy%22%3B%0A%20%0A%20try%20%7B%0A%20FileOutputStream%20fileOut%20%3D%20new%20FileOutputStream(%22.%2Femployee.txt%22)%3B%0A%20ObjectOutputStream%20out%20%3D%20new%20ObjectOutputStream(fileOut)%3B%0A%20out.writeObject(emp)%3B%0A%20out.close()%3B%0A%20fileOut.close()%3B%0A%20System.out.printf(%22Serialized%20data%20is%20saved%20in%20.%2Femployee.txt%20file%22)%3B%0A%20%7D%20catch%20(IOException%20i)%20%7B%0A%20i.printStackTrace()%3B%0A%20%7D%0A%20%7D%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

DeserializationClass.java (This class will be used to deserialize )

[pastacode lang=”java” manual=”package%20com.jbt%3B%0A%20%0Aimport%20java.io.*%3B%0A%20%0Apublic%20class%20DeserializationClass%20%0A%7B%0A%20public%20static%20void%20main(String%5B%5D%20args)%20%0A%7B%0A%20Employee%20emp%20%3D%20null%3B%0A%20try%20%0A%7B%0A%20FileInputStream%20fileIn%20%3D%20new%20FileInputStream(%22.%2Femployee.txt%22)%3B%0A%20ObjectInputStream%20in%20%3D%20new%20ObjectInputStream(fileIn)%3B%0A%20emp%20%3D%20(Employee)%20in.readObject()%3B%0A%20in.close()%3B%0A%20fileIn.close()%3B%0A%20%7D%20catch%20(IOException%20i)%20%0A%7B%0A%20i.printStackTrace()%3B%0A%20return%3B%0A%20%7D%20catch%20(ClassNotFoundException%20c)%20%0A%7B%0ASystem.out.println(%22Employee%20class%20not%20found%22)%3B%0A%20c.printStackTrace()%3B%0A%20return%3B%0A%20%7D%0A%20System.out.println(%22Deserializing%20Employee…%22)%3B%0A%20System.out.println(%22First%20Name%20of%20Employee%3A%20%22%20%2B%20emp.firstName)%3B%0A%20System.out.println(%22Last%20Name%20of%20Employee%3A%20%22%20%2B%20emp.lastName)%3B%0A%20%7D%0A%7D%0A%20%0A” message=”java code” highlight=”” provider=”manual”/]
  • Now execute “SerializationClass.java” and then “DeserializationClass.java”. It will first create a file with Employee object’s state and then while de-serialization it creates object from the same file.

Output:

Serialized data is saved in ./employee.txt file

Deserializing Employee…

First Name of Employee: wiki

Last Name of Employee: techy

  • Remove “serialVersionUID” variable from Employee.java file and again run “SerializationClass.java”  file.
  • It will create “employee.txt”  file again with  the object’s state .
  • Now let’s add a new variable in Employee class  suppose  String Address.

Employee.java

[pastacode lang=”java” manual=”package%20com.jbt%3B%0A%20%0Aimport%20java.io.Serializable%3B%0A%20%0Apublic%20class%20Employee%20implements%20Serializable%0A%7B%0A%20%20%20public%20String%20firstName%3B%0A%20%20%20public%20String%20lastName%3B%0A%20%20%20public%20String%20Address%3B%0A%20%20%20%2F%2FVariable%20is%20commented%20%0A%2F%2F%20%20%20private%20static%20final%20long%20serialVersionUID%20%3D%205462223600l%3B%0A%7D%0A%20%0A” message=”java code” highlight=”” provider=”manual”/]

Now run “DeserializationClass.java”

[ad type=”banner”]

Output:

java.io.InvalidClassException: com.jbt.Employee; local class incompatible: stream classdesc serialVersionUID = 5462223600, local class serialVersionUID = -3607530122250644586

at java.io.ObjectStreamClass.initNonProxy(Unknown Source)

at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)

at java.io.ObjectInputStream.readClassDesc(Unknown Source)

at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)

at java.io.ObjectInputStream.readObject0(Unknown Source)

at java.io.ObjectInputStream.readObject(Unknown Source)

at com.jbt.DeserializationClass.main(DeserializationClass.java:11)

  • It will throw an incompatible exception.
  • Because the given class Employee.java was changed in between serialization and de-serialization process.
  • Hence the system failed to identify that it is still the same class.
  • To make our system understand that it is the same class we have to make use of serialVersionUID variable inside class.

Categorized in: