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.
java code
import java.io.Serializable;

public class Employee implements Serializable
{

private static final long serialVersionUID = 1L;

String name;
String age;

public void setName(String name)
{
this.name = name;
}
public void setAge(String age)
{
this.age = age;
}

public String getName()
{
return this.name;
}

public String getAge()
{
return this.age;
}

@Override
public String toString()
{
return new StringBuffer(" Name : ")
.append(this.name)
.append(" Age : ")
.append(this.age).toString();
}
}
[ad type=”banner”]

WriteObject.java

  • A simple class to write / serialize the Employee object into a file – “c:\\employee.ser”
java code
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class WriteObject
{

public static void main (String args[])
{

Employee employee = new Employee();
employee.setName(“Wikitechy");
employee.setAge(“25");

try
{
FileOutputStream fout = new FileOutputStream("c:\\employee.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Done");

}catch(Exception ex)
{
ex.printStackTrace();
}
}
}

ReadObject.java

  • A simple class to read / deserialize the Employee object from file – “c:\\employee.ser”.
java code
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ReadObject
{
public static void main (String args[]) {

Employee employee;

try
{

FileInputStream fin = new FileInputStream("c:\\employee.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
employee = (Employee) ois.readObject();
ois.close();

System.out.println(employee);

}catch(Exception ex)
{
ex.printStackTrace();
}
}
}

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.
java code
package com.jbt;

import java.io.Serializable;

public class Employee implements Serializable
{
public String firstName;
public String lastName;
private static final long serialVersionUID = 5462223600l;
}
[ad type=”banner”]

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

java code
package com.jbt;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializaitonClass {

public static void main(String[] args) {
Employee emp = new Employee();
emp.firstName = "wiki";
emp.lastName = "techy";

try {
FileOutputStream fileOut = new FileOutputStream("./employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(emp);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in ./employee.txt file");
} catch (IOException i) {
i.printStackTrace();
}
}
}

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

java code
package com.jbt;

import java.io.*;

public class DeserializationClass
{
public static void main(String[] args)
{
Employee emp = null;
try
{
FileInputStream fileIn = new FileInputStream("./employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
emp = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i)
{
i.printStackTrace();
return;
} catch (ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserializing Employee...");
System.out.println("First Name of Employee: " + emp.firstName);
System.out.println("Last Name of Employee: " + emp.lastName);
}
}
  • 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

java code
package com.jbt;

import java.io.Serializable;

public class Employee implements Serializable
{
public String firstName;
public String lastName;
public String Address;
//Variable is commented
// private static final long serialVersionUID = 5462223600l;
}

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: