Guide to Serialization in Java

In this guide, we will learn the working of Serialization in Java.

What will you learn?


  • Overview of Serialization
  • Serialization with example - ObjectOutputStream class
  • Deserialization in java - ObjectInputStream class
  • Java Serialization with Inheritance (IS-A Relationship)
  • Java Serialization with Aggregation (HAS-A Relationship)
  • Java Serialization with a static data member
  • Externalizable in java 

Overview of Serialization

To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.io.Serializable interface or its subinterface.

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

Deserialization is the process of converting the serialized form of an object back into a copy of the object.
For example, the java.awt.Button class implements the Serializable interface so you can serialize a java.awt.Button object and store that serialized state in a file. Later, you can read back the serialized state and deserialize into a java.awt.Button object.

It is mainly used in Hibernate, RMI, JPA, EJB and JMS technologies.
Advantage: It is mainly used to travel object's state on the network (known as marshaling).

Serialization with an example(java.io.Serializable interface)

Serializable is a marker interface (has no data member and method). It is used to "mark" java classes so that objects of these classes may get the certain capability. The String class and all the wrapper classes implement a java.io.Serializable interface by default. 
Example:
class Employee implements Serializable {
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;
 private transient int age;
 
 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 int getAge() {
  return age;
 }
 
 public void setAge(int age) {
  this.age = age;
 }
}
In the above example, the Employee class implements the Serializable interface. Now its objects can be converted into a stream.

ObjectOutputStream class

The ObjectOutputStream class 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. 
In this Serialization 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 employees.txt. Let's create a class Employee which implements the Serializable interface.
class Employee implements Serializable {
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;

 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;
 }
}
Now write the code to serialize the object. 
In the example, serializeProcessing() private methods perform serialization.
public class Serialization {

 public static void main(String[] args) throws Exception {
  
  final Employee employee = new Employee();
  employee.setId(100);
  employee.setName("ramesh");
  serializeProcessing(employee);
 }

 private static void serializeProcessing(Employee employee)
   throws IOException {
  final FileOutputStream fout = new FileOutputStream("employees.txt");
  final ObjectOutputStream out = new ObjectOutputStream(fout);
  out.writeObject(employee);
  out.flush();
  System.out.println("success");
 }

}

Deserialization 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. 
In this deserialization example, deSerializeProcessing() does the deserialization process.
public class DeSerializationExample {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
  
  final Employee employee = new Employee();
  employee.setId(100);
  employee.setName("ramesh");
  deSerializeProcessing(employee);
 }

 private static void deSerializeProcessing() throws IOException, ClassNotFoundException {
  final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "employees.txt"));
  final Employee employee = (Employee) in.readObject();
  System.out.println(" printing employee object details");
  System.out.println(employee.getId() + " " + employee.getName());
  
  System.out.println(" printing address object details");
  System.out.println(employee.getAddress().getCity());
  in.close();
 }

}

class Employee implements Serializable {
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;

 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;
 }
}

Java Serialization with Inheritance (IS-A Relationship)

If a class implements a Serializable interface then all its subclasses will also be serializable. Let's see the example:
public class SerializationWithInheritance {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
  final Person employee = new Employee1();
  employee.setId(100);
  employee.setName("ramesh");
  serilizeProcessing(employee);
  deSerilizeProcessing();
 }
 
 private static void serilizeProcessing(Person employee)
   throws IOException {
  final FileOutputStream fout = new FileOutputStream("f.txt");
  final ObjectOutputStream out = new ObjectOutputStream(fout);
  out.writeObject(employee);
  out.flush();
  out.close();
  System.out.println("success");
 }

 private static void deSerilizeProcessing() throws IOException, ClassNotFoundException {
  final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "f.txt"));
  final Employee1 employee = (Employee1) in.readObject();
  System.out.println(" printing employee object details");
  System.out.println(employee.getId() + " " + employee.getName());
  in.close();
 }
}

class Person implements Serializable{
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;

 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;
 }
 
 
}

class Employee1 extends Person{

}
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 the parent class is Serializable, subclass would also be.

Java Serialization with Aggregation (HAS-A Relationship)

If a class has a reference to another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.
Example:
public class SerializationWithAggregation {
 public static void main(String[] args) throws IOException, ClassNotFoundException {
  final Address address = new Address();
  address.setCity("pune");
  address.setState("Maharashtra");
  final Employee employee = new Employee();
  employee.setAddress(address);
  employee.setId(100);
  employee.setName("ramesh");
  serilizeProcessing(employee);
  deSerilizeProcessing();
 }

 private static void serilizeProcessing(Employee employee)
   throws IOException {
  final FileOutputStream fout = new FileOutputStream("f.txt");
  final ObjectOutputStream out = new ObjectOutputStream(fout);
  out.writeObject(employee);
  out.flush();
  System.out.println("success");
 }

 private static void deSerilizeProcessing() throws IOException, ClassNotFoundException {
  final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "f.txt"));
  final Employee employee = (Employee) in.readObject();
  System.out.println(" printing employee object details");
  System.out.println(employee.getId() + " " + employee.getName());
  
  System.out.println(" printing address object details");
  System.out.println(employee.getAddress().getCity());
  in.close();
 }

}

class Employee implements Serializable {
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;
 private Address address;

 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 Address getAddress() {
  return address;
 }

 public void setAddress(Address address) {
  this.address = address;
 }

}

class Address implements Serializable {
 private static final long serialVersionUID = 1L;
 private String city;
 private String state;
 private String streetName;

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public String getState() {
  return state;
 }

 public void setState(String state) {
  this.state = state;
 }

 public String getStreetName() {
  return streetName;
 }

 public void setStreetName(String streetName) {
  this.streetName = streetName;
 }

}
If you don't serialize the Address class then you can not serialize the instance of Employee class. In the above example, Address class is serialized so we can serialize the instance of Employee class.
Important: All the objects within an object must be Serializable.

Java Serialization with a static data member

If there is any static data member in a class, it will not be serialized because static is the part of class not object.
Example:
public class SerializationWithStaticDataMember {
 public static void main(String[] args) throws IOException, ClassNotFoundException {
  final Employee2 employee = new Employee2();
  employee.setId(100);
  employee.setName("ramesh");
  serilizeProcessing(employee);
  deSerilizeProcessing();
 }

 private static void serilizeProcessing(Employee2 employee)
   throws IOException {
  final FileOutputStream fout = new FileOutputStream("f.txt");
  final ObjectOutputStream out = new ObjectOutputStream(fout);
  out.writeObject(employee);
  out.flush();
  out.close();
  System.out.println("success");
 }

 private static void deSerilizeProcessing() throws IOException, ClassNotFoundException {
  final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "f.txt"));
  final Employee2 employee = (Employee2) in.readObject();
  System.out.println(" printing employee object details");
  System.out.println(employee.getId() + " " + employee.getName());
  System.out.println(employee.getCompany());
  in.close();
 }
}

class Employee2 implements Serializable {
 private static final long serialVersionUID = 1L;
 private int id;
 private String name;
 private static String company = "XYZ";

 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 static String getCompany() {
  return company;
 }
}
Java Serialization with array or collection
**Rule:** In case of array or collection, all the objects of array or collection must be serializable.
 If any object is serializable, serialization will be failed.

Externalizable 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

Related Posts

Comments