Serialization in Java

Serialization in java is a mechanism of writing the state of an object into a byte stream.

What is Serialization?
- Serializable is a marker interface. When an object has to be transferred over a network ( typically through rmi or EJB) or persist the state of an object to a file, the object Class needs to implement Serializable interface. Implementing this interface will allow the object converted into bytestream and transfer over a network.

Advantage of Java Serialization
It is mainly used to travel object's state on the network (known as marshaling).

What is the need of Serialization?
The serialization is used :-
  • To send state of one or more object’s state over the network through a socket.
  • To save the state of an object in a file.
  • An object’s state needs to be manipulated as a stream of bytes.
What is use of serialVersionUID?
-During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type
Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:
  • Add fields
  • Change a field from static to non-static
  • Change a field from transient to non-transient
  • Add classes to the object tree
List of incompatible changes:
  • Delete fields
  • Change class hierarchy
  • Change non-static to static
  • Change non-transient to transient
  • Change type of a primitive field
So, if no suid is present , inspite of making compatible changes, jvm generates new suid thus resulting in an exception if prior release version object is used .
The only way to get rid of the exception is to recompile and deploy the application again.

If we explicitly metion the suid using the statement:
private final static long serialVersionUID = <integer value> 
then if any of the metioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.

java.io.Serializable interface
Serializable is a marker interface (without body). It is just used to mark java classes which support a certain capability.
It must be implemented by the class whose object you want to persist. Let's see the example given below:
import java.io.Serializable;  
public class Employee implements Serializable{  
 int empid;  
 String empname;  
 public Employee(int empid, String empname) {  
  this.empid = empid;  
  this.empname = empname;  
 }  
}  
ObjectOutputStream class
An ObjectOutputStream is used to write primitive data types and Java objects to an OutputStream. Only objects that support the java.io.Serializable interface can be written to streams.

Constructor-
public ObjectOutputStream(OutputStream out) throws IOException {}creates an ObjectOutputStream that writes to the specified OutputStream.
Methods-
public final void writeObject(Object obj) throws IOException {}writes the specified object to the ObjectOutputStream.
 public void flush() throws IOException {}flushes the current output stream.
 public void close() throws IOException {}closes the current output stream.
Example of Java Serialization
In this example, we are going to serialize the object of Employee class. The writeObject() method of ObjectOutputStream class provides the functionality to serialize the object. We are saving the state of the object in the file named emp.txt.
import java.io.*;  
class PersistTest{  
 public static void main(String args[])throws Exception{  
  Employee emp = new Employee(100,"Dinesh");  
  FileOutputStream fileout = new FileOutputStream("emp.txt");  
  ObjectOutputStream out = new ObjectOutputStream(fileout);  
  out.writeObject(emp);  
  out.flush();  
  System.out.println("success write");  
 }  
}  
output:
success write

Deserilization in java
Deserialization is the process of reconstructing the object from the serialized state.It is the reverse operation of serialization.

ObjectInputStream class
An ObjectInputStream deserializes objects and primitive data written using an ObjectOutputStream.

Constructor
public ObjectInputStream(InputStream in) throws IOException {}creates an ObjectInputStream that reads from the specified InputStream.
Methods
public final Object readObject() throws IOException, ClassNotFoundException{}reads an object from the input stream.
public void close() throws IOException {}closes ObjectInputStream.

Example of Java Deserialization

import java.io.*;  
class DepersistTest{  
 public static void main(String args[])throws Exception{  
  ObjectInputStream in = new ObjectInputStream(new FileInputStream("emp.txt"));  
  Employee emp = (Employee)in.readObject();  
  System.out.println(emp.empid+" "+emp.empname);  
  in.close();  
 }  
}  
Output:
100 Dinesh

Other than Serialization what are the different approach to make object Serializable?

Besides the Serializable interface, at least three alternate approaches can serialize Java objects:

1)For object serialization, instead of implementing the Serializable interface, a developer can implement the Externalizable interface, which extends Serializable. By implementing Externalizable, a developer is responsible for implementing the writeExternal() and readExternal() methods. As a result, a developer has sole control over reading and writing the serialized objects.

2)XML serialization is an often-used approach for data interchange. This approach lags runtime performance when compared with Java serialization, both in terms of the size of the object and the processing time. With a speedier XML parser, the performance gap with respect to the processing time narrows. Nonetheless, XML serialization provides a more malleable solution when faced with changes in the serializable object.

3)Finally, consider a "roll-your-own" serialization approach. You can write an object's content directly via either the ObjectOutputStream or the DataOutputStream. While this approach is more involved in its initial implementation, it offers the greatest flexibility and extensibility. In addition, this approach provides a performance advantage over Java serialization.

Are the static variables saved as the part of serialization?
- No. The static variables belong to the class and not to an object they are not the part of the state of the object so they are not saved as the part of serialized object.

To serialize an array or a collection all the members of it must be serializable. True /False?
Ans- true.

Serialization with Inheritance (IS-A Relationship)
If a class implements serializable then all its sub classes will also be serializable. Let's see the example given below:
import java.io.Serializable;  
class Person implements Serializable{  
 int id;  
 String name;  
 Person(int id, String name) {  
  this.id = id;  
  this.name = name;  
 }  
}  
class Employee extends Person{  
 String department;  
 int salary;  
 public Employee(int empid, String empname, String department, int salary) {  
  super(empid, empname);  
  this.department = department;  
  this.salary = salary;  
 }  
}  
Now you can serialize the Employee class object that extends the Person class which is Serializable. Parent class properties are inherited to subclasses so if parent class is Serializable, subclass would also be.

Serialization with Aggregation (HAS-A Relationship)
If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.
class Address{  
 String addressLine,city,state;  
 public Address(String addressLine, String city, String state) {  
  this.addressLine=addressLine;  
  this.city=city;  
  this.state=state;  
 }  
}  
import java.io.Serializable;  
public class Employee implements Serializable{  
 int empid;  
 String empname;  
 Address address;//HAS-A  Relation
 public Employee(int empid, String empname) {  
  this.empid = empid;  
  this.empname = empname;  
 }  
}  
Since Address is not Serializable, you can not serialize the instance of Empoyee class.

Externalizable interface in java
The Externalizable interface provides the facility of writing the state of an object into a byte stream in compress format. It is not a marker interface.

The Externalizable interface provides two methods:
  • public void writeExternal(ObjectOutput out) throws IOException
  • public void readExternal(ObjectInput in) throws IOException
Are the static variables saved as the part of serialization?
Ans- No. The static variables belong to the class and not to an object they are not the part of the state of the object so they are not saved as the part of serialized object.




No comments:

Post a Comment