Java Serialization and Deserialization Explained: A Practical Guide for Beginners
How does Java save objects to a file? How does an application store the data of an object or send it to another system?
To work with file handling, with distributed applications, with caching or even with some kinds of data transfer, Java offers the option of Serialization and Deserialization.
Java Serialization Tutorial: A Deep DIVE into Serialization and Deserialization Examples
What Is Serialization in Java?
Here is the basic idea of Java Serialization. Java Serialization is a function provided by the Java programming language that enables us to convert objects into byte form in order to store them in files or over the network and then read them from files or network and use them in our programs.
Java serialization helps us to save objects in files for further use.
For example, imagine a student management application.
For example, imagine a student management application. A student object contains information such as:
• Student ID
• Student name
• Course name
• Marks
If we wish to store this state of the object to use it later on, Java Serialization can assist us in writing the state of the object into the file.
Why Do We Need Serialization?
Serialization can be useful when we need to:
• Save an object's state in a file.
• Transfer objects between Java applications.
• Store objects temporarily for later use.
• Support certain caching and distributed application workflows.
Note that in Java serialization is not the only way to store data. Most of the time databases, JSON, and other data storage formats would be more suitable to the job in hand.
What Is Deserialization In Java?
Deserialization is just the reverse of serialization, therefore, deserialization means reading the object from the byte stream.
In your program, you have serialized some data of an object (Student) into a file. And now you would like to read this file in order to extract the details such as the name of the student, the course he is taking, and his marks.
The basic process looks like this:
Java Object → Serialization → Byte Stream → File
File → Deserialization → Java Object
Serialization and Deserialization are two ways to save and retrieve objects respectively.
How Does Serialization Work in Java?
There is a package called java.io which is used for Serialization and Deserialization. following classes and interfaces are used for frequent purposes:
• ObjectOutputStream: This writes objects to the output stream.
• ObjectInputStream: This reads objects from the input stream.
• ObjectInputStream: This reads objects from the input stream.
• FileOutputStream: Writes bytes to a file.
• FileInputStream: Used to read bytes from a file.
For serializing a normal Java object, its class should have implemented the Serializable interface, and it needs to satisfy Java serialization rules. Let us understand this through a practical example.
Practical Example: Java Serialization and Deserialization We will create a Student class, save its object in a file, and then read the saved object back. Step 1: Create the Student Class
Create a Java class named Student.java.
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
int id;
String name;
String course;
double marks;
public Student(int id, String name,
String course, double marks) {
this.id = id;
this.name = name;
this.course = course;
this.marks = marks;
}
public void display() {
System.out.println("Student ID: " + id);
System.out.println("Student Name: " + name);
System.out.println("Course: " + course);
System.out.println("Marks: " + marks);
}
}
Here is what the important parts mean:
• implements Serializable allows the class to participate in Java serialization. • serialVersionUID identifies the version of the serialized class. • The constructor initializes the student's data.
• The display() method prints the student's details.
The Serializable interface does not require us to implement any methods. Step 2: Serialize the Student Object
Create another class named SerializeDemo.java.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializeDemo {
public static void main(String[] args) {
Student s1 = new Student(
101, "Rahul", "Java", 85.5
);
try (ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream("student.ser"))) { out.writeObject(s1);
System.out.println(
"Student object serialized successfully."
);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Expected output:
Student object serialized successfully.
As we execute this code, the program generates a file called student.ser in the working directory of the application, provided the process is successful.
This writeObject() function writes the serialized data of the student object into the file. Using the try-with-resources construct, the streams are closed after execution. Step 3: Deserializing the Student Object
Now define a class called DeserializeDemo.java.
import java.io.FileInputStream;
import java.io.ObjectInputStream;
Deserialize the Student Object
Now create a class named DeserializeDemo.java.
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializeDemo {
public static void main(String[] args) {
try (ObjectInputStream in =
new ObjectInputStream(
new FileInputStream("student.ser"))) {
Student s =
(Student) in.readObject();
System.out.println(
"Student object deserialized successfully." );
s.display();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Expected output:
Student object deserialized successfully.
Student ID: 101
Student Name: Rahul
Course: Java
Marks: 85.5
The readObject() method reads the serialized data and generates the object from that data. Type casting is necessary as readObject() returns the Object type.
Important Note: You need to run SerializeDemo before this as you need the file. Also, Student class should be accessible in the classpath while running DeserializeDemo.
What Is the Serializable Interface?
Serializable is one of the most important interfaces used in Java serialization.
This interface belongs to the java.io package and is a marker interface. A marker interface is used to indicate certain features of the class without implementing any methods.
Example:
import java.io.Serializable;
class Employee implements Serializable {
int id;
String name;
}
In this case, since the class Employee is implementing the Serializable interface, hence its eligible object state can be serialized.
If we don’t implement Serializable, serializing any instance of this class will throw an exception NotSerializableException
What is the serialVersionUID in Java?
The serialVersionUID in Java is the serial version identifier in Java serialization process.
Suppose you have an object which is being serialized now but after that, there are some changes done to the class definition before deserializing the object state.
In Java, the serialVersionUID aids in ensuring compatibility between the serialized object data and class definition. If there is any kind of incompatibility, deserialization may not work, and an error message may be generated: InvalidClassException.
Example:
private static final long serialVersionUID = 1L;
In this particular instance, the Employee class is Serializable and hence the state of the object can be serialized.
In this case, the appropriate way to act is by defining a serialVersionUID in the class. Having the same version ID does not necessarily imply that all modifications to the class would be backward compatible.
What is the transient Keyword in Java Serialization?
There may be cases where we do not want some instance variable to be part of the default serialized form of the object.
The transient keyword in Java Serialization serves this purpose.
Here is an example of how the transient keyword can be used:
import java.io.Serializable;
Consider this example:
import java.io.Serializable;
class User implements Serializable {
int id;
String username;
transient String password;
}
Here, password is declared as transient.
During default serialization, the value of this field is not saved. the field is initialized with the default value. If the type is a reference type, such as String, then the default value of the type is null.
The traAftensient keyword could be helpful for those fields that are not supposed to be serialized by default.
Nevertheless, the use of this keyword is not regarded as an adequate measure to provide security. Sensitive data must be protected in an adequate manner.
But it must not be regarded as a comprehensive security measure. Sensitivity of the data should be handled in the proper manner.
Difference Between Serialization and Deserialization
Serialization Deserialization
Converts an object's state into a byte stream. Reconstructs an object from a byte stream. Uses ObjectOutputStream. Uses ObjectInputStream.
Commonly uses writeObject(). Commonly uses readObject(). Can save serialized data to a file. Can read saved serialized data.
These two processes happen to be interrelated when it comes to saving and restoring an object's state.
Common Errors in Java Serialization
Beginners may face a few common problems while practising serialization. 1. NotSerializableException
It will arise due to the fact that the object to be serialized does not fulfill the requirements of serialization.
Solution: Determine if the class has implemented the Serializable interface and that the non-transient fields of the object are serializable.
2. FileNotFoundException
It arises when the file is missing or there is a problem with the file path.
Solution: The file path should be correct, and serialization should have taken place before deserialization.
Such an error occurs when the file is not available or there is a wrong file path.
3. InvalidClassException
These kinds of exceptions occur when the serialVersionUID of the serialized objects and the class does not match.
Solution: Make sure that the changes made in the class are compatible with the serialVersionUID. 4. ClassNotFoundException
This exception occurs if the required class cannot be found in order to recreate the object. Solution: Ensure that the necessary class is in the class path of the program.
Best Practices for Serialization
Here are some best practices for serialization in Java:
• Use serialization only when it makes sense for your application.
• Use serialization only when it fits the application's requirements.
• Define and manage serialVersionUID carefully.
• • Use transient if the field needs to be excluded from default serialization process. • Be careful about file and serialization exceptions. • Never deserialize data from untrusted sources as Java native deserialization poses serious security concerns.
• Use JSON or other data formats in situations requiring inter-operability and/or data storage.
Real-World Uses of Serialization
Java serialization has several possible applications:
Object persistence: It is possible to store an object state in an application and restore it later.
Distributed systems: In some Java-based systems, there is serialization-based transfer of objects' representations between different system parts.
Caching: Certain caching implementations may serialize objects when storing them outside the application's immediate memory.
Session management: There might be situations in which Java application servers/frameworks allow for the serialization of session-related objects under certain configurations.
The choice of particular technique is normally dictated by the particular technology in use. Recent years have seen the rise of use of databases, JSON and many other technologies to store the state of objects rather than Java serialization.
Conclusion
Serialization and Deserialization: Storing and bringing back objects.
In this tutorial, we have covered the Serializable interface, ObjectOutputStream, ObjectInputStream, serialVersionUID, and transient. We created a student object, stored it in a file, and retrieved the object from the file using Java programming.
The best way to learn these concepts for beginners is to execute both programs, examine the generated file, and modify different attributes.
Learning these concepts enables one to develop strong skills in Java file handling and managing objects. On the other hand, one needs to understand the limitations of native serialization when it comes to security issues.
Author:
Aarti Choudhary
Related Links:
Resume Tips For Software Developers
Do visit our channel to know more: SevenMentor
Aarti Choudhary
Expert trainer and consultant at SevenMentor with years of industry experience. Passionate about sharing knowledge and empowering the next generation of tech leaders.