Serialization is a process in Java that allows you to convert an object's state into a byte stream, which can be stored in a file, transmitted over a network, or saved in a database. Deserialization, on the other hand, is the reverse process where you convert a byte stream back into an object's state. Serialization is essential for tasks like saving and restoring object states, transmitting objects over the network, or caching objects. In this Core Java tutorial, we'll explore serialization and deserialization in detail, providing explanations and examples.
Serialization:
Serialization in Java is achieved by implementing the 'Serializable' interface, which is a marker interface (an interface with no methods). When a class implements 'Serializable', it signifies that its objects can be serialized.
Example of Serialization:
import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Name: " + name + ", Age: " + age;
}
}
public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
try (FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
// Serialize the object to a file
objectOut.writeObject(person);
System.out.println("Serialization completed.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example, the 'Person' class implements 'Serializable'. We then create a 'Person' object and serialize it to a file named "person.ser" using 'ObjectOutputStream'.
Deserialization:
Deserialization is the process of converting a byte stream back into an object. It's the reverse operation of serialization. To perform deserialization, the class of the object being deserialized must also implement 'Serializable'.
Example of Deserialization:
import java.io.*;
public class DeserializationExample {
public static void main(String[] args) {
try (FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
// Deserialize the object from the file
Person person = (Person) objectIn.readObject();
System.out.println("Deserialization completed.");
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In this example, we read the serialized object from the "person.ser" file and deserialize it using 'ObjectInputStream'. We then cast the deserialized object to the 'Person' class.
Serialization and Versioning:
It's essential to consider versioning when using serialization, especially in distributed systems. If the structure of a serialized object changes (e.g., fields added or removed), deserialization may fail if the receiving side has a different version of the class.
To handle versioning, you can use the 'serialVersionUID' field to specify a unique identifier for the serialized class. If the identifier does not match between the sender and receiver, deserialization will fail, allowing you to handle version mismatches gracefully.
private static final long serialVersionUID = 123456789L;
Custom Serialization:
You can customize the serialization and deserialization process by implementing the 'writeObject' and 'reaObject' methods in your class. This allows you to control how the object's state is written to and read from the byte stream.
Serialization and deserialization in Java allow you to persist and restore object states efficiently. Understanding how to implement the'Serializable' interface, serialize objects, and handle versioning is essential for tasks like object persistence, data transmission, and caching in Java applications.