‘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.