Java serialization in Inheritance
In Java, serialization works with inheritance in the following way:
- If a class implements
Serializable
, its subclasses will also be serializable, regardless of whether the subclasses implementSerializable
or not. - When a subclass is serialized, the state of its superclass is also serialized, if the superclass implements
Serializable
. - If a superclass does not implement
Serializable
, the state of that superclass is not serialized, and during deserialization, a new instance of the superclass will be created using the default constructor.
Therefore, it is important to consider the serialization behavior of superclasses when designing a serializable subclass. If a superclass is not serializable, its state will not be preserved during serialization, and during deserialization, the superclass’s state will be lost.
You can control the serialization of superclass fields by declaring them as transient
or by using the writeObject
and readObject
methods to have custom serialization logic for the superclass.
In Summary:
- If Parent class does not implement Serializable and Child class implement Serializable then Child class can be Serializable
- At the time of Serialization, JVM will check that any instance variable is inheriting from non Serializable Parent or not. If parent is not marked with Serializable then default value of Parent Object will be saved to file.
- At the time of De-Serialization, JVM will check that Parent is Serializable or not. If parent is not Serializable then default Object will be created.
Example code Serialization in inheritance in Java:
import java.io.*;
class Animal implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class Dog extends Animal {
private static final long serialVersionUID = 1L;
private String breed;
public Dog(String name, int age, String breed) {
super(name, age);
this.breed = breed;
}
public String getBreed() {
return breed;
}
}
public class SerializationInheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog("Fido", 5, "Labrador");
// Serializing the object
try (FileOutputStream fileOut = new FileOutputStream("dog.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(dog);
} catch (IOException e) {
e.printStackTrace();
}
// Deserializing the object
try (FileInputStream fileIn = new FileInputStream("dog.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
Dog deserializedDog = (Dog) in.readObject();
System.out.println("Name: " + deserializedDog.getName());
System.out.println("Age: " + deserializedDog.getAge());
System.out.println("Breed: " + deserializedDog.getBreed());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In this example, the Animal
class is a base class that implements Serializable
. The Dog
class extends the Animal
class and adds a new breed
field.
The main
method serializes a Dog
object to a file called dog.ser
using a FileOutputStream
and an ObjectOutputStream
. The ObjectOutputStream
is used to write the object to the FileOutputStream
.
The main
method also deserializes the Dog
object from the dog.ser
file using a FileInputStream
and an ObjectInputStream
. The ObjectInputStream
is used to read the object from the FileInputStream
, and the object is cast to a Dog
object.
The output of this program will be:
Name: Fido
Age: 5
Breed: Labrador