Serialization and de-serialization are processes in Java (and in programming in general) that involve converting an object into a byte stream and vice versa. This is particularly useful when you need to transfer or store an object’s state, such as when sending it over a network or persisting it to a file.
Java Serialization
Serialization in Java is the concept of representing an object’s state as a byte stream. The byte stream has all the information about the object. Usually used in Hibernate, JMS, JPA, and EJB, serialization in Java helps transport the code from one JVM to another and then de-serialize it there.
To serialize an object into a byte stream, we need to call the writeObject() method of the ObjectOutputStream class.
Serialization:
- Definition: Serialization is the process of converting an object’s state (fields and data) into a byte stream.
- Purpose: It allows you to save the state of an object, so it can be reconstructed later.
- Java Interface: The
Serializable
interface in Java is a marker interface that indicates a class can be serialized.
Example.
import java.io.Serializable; public class Employee implements Serializable { int id; String name; // }
Deserialization in Java
Deserialization is the exact opposite process of serialization where the byte data type stream is converted back to an object in the memory. The best part about these mechanisms is that both are JVM-independent, meaning you serialize on one JVM and de-serialize on another.
The method used to deserialize a byte stream into an object is readObject() method of ObjectInputStream class.
Constructor of ObjectInputStream class
We use the constructor of the ObjectOutputStream class that has the following syntax:
public ObjectInputStream(InputStream in) throws IOException { //code }
This constructor creates an ObjectInputStream that reads from the specified InputStream.
Important Methods of ObjectInputStream class
There are some important methods in the ObjectInputStream class that help us to deserialize an object. These methods are listed in the following table:
Deserialization:
- Definition: Deserialization is the process of reconstructing an object from a byte stream.
- Purpose: It allows you to recreate the original object from the saved state.
- Java Interface: Classes that implement
Serializable
should be deserialized.
Example :
public class Deserialization { public static void main(String args[]) { try { //Creating stream to read the object ObjectInputStream input = new ObjectInputStream(new FileInputStream("employee.ser")); Employee employee = (Employee )input.readObject(); //printing the data of the serialized object System.out.println(“The id of the Employee is:” +employee.id); System.out.println(“The name of the Employee is:” +employee.name); //closing the stream input.close(); } catch(Exception e) { System.out.println(e); } } }
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:
class Employee implements Serializable { int id; String name; Employee(int id, String name) { this.id = id; this.name = name; } }
class University extends Employee { String subjectName; double salary; public University(int id, String name, String subjectName, double salary) { super(id,name); this.subjectName= subjectName; this.salary = salary;; } }
Now we can easily serialize the object of the University class that extends the Employee class. As the Employee class is Serializable, the University class will automatically become Serializable without implementing the Serializable interface.
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.
public class Address { String post; double Street; // }
public class Employee implements Serializable { int id; String name; Address address; //HAS-A relationship public Employee(int id, String name) { this.id = id; this.name = name; } }
Why to use the transient keyword
Transient keyword can only be applied to fields or member variables. Applying it to the method or local variable is a compilation error
Transient and static
Since static fields are not part of state of the object, there is no use/impact of using transient keyword with static variables. However there is no compilation error.
Transient and final
Final variables are directly serialized by their values, so there is no use/impact of declaring final variable as transient. There is no compile-time error though.
Java Serialization with a static data member
class Student implements Serializable { int id; String name; static String aadhar = "ABCD123456789DDFDGFAA"; //We can’t serialize the static member transient String PanNo ="QWERRTYQQ" //We can’t serialize the transient member public Student(int id, String name) { this.id = id; this.name = name; } }
Inheritance in Serialization in java:
Now we will see how inheritance affects serialization.So there can be multiple cases whether super class is serializable or not.If not then how will you handle that and how it works.
if superclass is Serializable?
If superclass is serializable then all its subclasses are automatically serializable.
if superclass is not Serializable?
If super class is not serializable then we have to handle it quite differently.
- If superclass is not serializable then it must have no argument constructor.
If superclass is not Serializable then all values of the instance variables inherited from super class will be initialized by calling constructor of Non-Serializable Super class during deserialization process.
What if superclass is Serializable but you don’t want subclass to be Serializable
If you don’t want subclass to be Serializable
then you need to implement writeObject()
and readObject()
method in subclass and need to throw NotSerializableException from these methods.
Case -Can you Serialize static variables?
No, we can’t. As we know static variable is at a class level not at the object level and you serialize an object so you can’t serialize static variables.
Conclusion
In summary, serialization in Java involves converting an object into a byte stream, enabling its storage or transmission and deserialization reconstructs the original object from the byte stream. These processes are crucial for tasks like saving object states to files, sending objects over networks, or persisting data in databases, ensuring data can be easily stored, transferred, and later reconstructed.
- You can’t serialize static variables.
- If you don’t want to serialize any field,then make it transient.
- If you want to serialize any class then it must implement Serializable interface which is marker interface.
- Marker interface in Java is interface with no field or methods or in simple word empty interface in java is called marker interface
- Serialization in java is the translation of your Java object’s values/states to bytes to send it over network or save it.On other hand,Deserialization is conversion of byte code to corresponding java objects.
- Good thing about Serialization is entire process is JVM independent, meaning an object can be serialized on one platform and deserialized on an entirely different platform.
- serialVersionUID is used to ensure that same object(That was used during Serialization) is loaded during Deserialization.serialVersionUID is used for version control of object.
- When you serialize any object and if it contain any other object reference then Java serialization serialize that object’s entire object graph.
- If superclass is Serializable then its subclasses are automatically Serializable.
- If superclass is not Serializable then all values of the instance variables inherited from super class will be initialized by calling constructor of Non-Serializable Super class during deserialization process.
- If you don’t want subclass to serializable then you need to implement writeObject() and readObject() method and need to throw NotSerializableException from this methods.