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 implement Serializable 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:

  1. If Parent class does not implement Serializable and Child class implement Serializable then Child class can be Serializable
  2. 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.
  3. 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