Serialization in Java

‘What is serialization in Java?’ is a question faced by most of the Java developers  quite  often In this discussion we are trying to figure it out the concept of Java object serialization  with some code samples.

Concept of Serialization in Java

Serialization in Java is a mechanism by which a Java  object can be converted to  byte stream and that stream can be written to file.Later the same object can be read from the file  . This process is JVM  as well as platform independent .So an object serialized in one JVM can be deserialized   in any other JVM.

For an object to be serialized , the class should implement the marker interface Serializable.A marker interface is nothing but an interface without any method in it.Classes ObjectOutputStream in java.io package is having writeObject()  method. An object can be written to a file using this method. Similarly ObjectInputStream class has readObject method . Now see the code snippets shown below for more clarifications.

Here I am trying to create an Employee class which I need to serialize .The only thing I did is just implemented the Serializable interface.

import java.io.Serializable;
public class Employee implements Serializable {
private int id;
private String name;
private String department;
private double expLevel;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

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

public String getDepartment() {
return department;
}

public void setDepartment(String department) {
this.department = department;
}

public double getExpLevel() {
return expLevel;
}

public void setExpLevel(double expLevel) {
this.expLevel = expLevel;
}
}

Now let us see  the main class to perform the serialization process. It is opening a file in the /tmp directory of the drive where the workspace is located(in case of Windows). Then creating ObjectOutputStream object with which I am writing  an Employee object to the file.Then creating an ObjectInputStream object and using that object I am reading the object from the file.In this case we are writing only one object to file. So whatever we have written to file , the same thing we need to retrieve.

import java.io.*;
public class EmployeeMain {
public static void main(String[] args) {
File file = new File("/tmp/empserialization.txt");

try {
FileOutputStream foStream = new FileOutputStream(file);
ObjectOutputStream oStream = new ObjectOutputStream(foStream);
Employee employee = new Employee();
employee.setId(1);
employee.setName("Bijoy");
employee.setDepartment("Instrumentation");
employee.setExpLevel(5.0);
System.out.println("Object values to be serialized = "+employee.getName() +";" +employee.getId() +";"+employee.getDepartment() +";"
+employee.getExpLevel());
oStream.writeObject(employee);
ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(file));
Employee emp = (Employee)iStream.readObject();
System.out.println("De serialized object values = "+emp.getName() +";"+emp.getId() +";"+emp.getDepartment() +";"
+emp.getExpLevel());
oStream.close();
iStream.close();

} catch (FileNotFoundException fn) {
fn.printStackTrace();

} catch (IOException io) {
io.printStackTrace();
}catch(ClassNotFoundException cnf){
cnf.printStackTrace();
}
}
}

Now let us examine the output

Object values to be serialized = Bijoy;1;Instrumentation;5.0

De serialized object values =  Bijoy;1;Instrumentation;5.0

For an object is to be serialized , the individual attributes also should be Serializable

Transient variable in Serialization

If one attribute need not be serializable then that should be specified as transient. In the above example all the attributes are non transient.So we retrieved the same data. If we specify one attribute as transient , that attribute won’t be serialized. The default value for that attribute will be generated (for double it will be 0.0 ). This feature is very important when one attribute is insignificant.  Now just put a transient keyword for attribute expLevel in Employee.java.

private  transient double expLevel;

Now the changed Employee.java

import java.io.Serializable;
public class Employee implements Serializable {
private int id;
private String name;
private String department;
private transient double expLevel;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

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

public String getDepartment() {
return department;
}

public void setDepartment(String department) {
this.department = department;
}

public double getExpLevel() {
return expLevel;
}

public void setExpLevel(double expLevel) {
this.expLevel = expLevel;
}
}

Now  let us see the output.

Object values to be serialized = Bijoy;1;Instrumentation;5.0

De serialized object values =  Bijoy;1;Instrumentation;0.0

Here we specified the expLevel as transient. So the expLevel has not been serialized. The default value for double  was set as the value.

serialVersionUID in Serialization

Serialization process is associated with an id for each object. If we have not specified an ID during coding , the default id will be allocated. If we are creating a class  it is better we define our own id  like:

private static final long serialVersionUID = 2L;

Suppose you and your team mate together doing a piece of code . So you are making  structural changes in the Serializable class.And you are not changing the serialVersionUID . So your teammate is not aware of your changes. And you are sending the list of  objects to him in a file.But at his side , the exact data wont be retrieved. To avoid this , whenever you are making core changes , you should change the serialVersionUID too. If the class with specified serialVersionUID is not there in your teammates environment  InvalidClassException  will be thrown.

See Related Discussions:

Externalization in Java

Collections framework

Threading Tutorial