InvalidClassException: no valid constructor

serialize / deserialize

This is an exception thrown when the class cannot be deserialized from the stream.

A class is Serializable when it extends Serializable interface. Note that the super class doesn’t need to be serializable. After serialization, all the states of the class will be saved to the stream except transient ones.

  1. class or its super class needs to be Serializable, otherwise NotSerializableException.
  2. all the fields of the class need to be Serializable or be marked as transient, otherwise NotSerializableException.
  3. if super class is not serializable, the states inherited from super class will only have default values.

Deserialization is the reverse process of serialization, it reads from the stream and reconstruct the class instance.

  1. if the super class is not serializable, the super class must have a no-arg constructor otherwise InvalidClassException: no valid constructor.
import java.io.*;

public class SerializableTest {
  static class Super {
    int a;

    public Super(int a) {
      this.a = a;
    }
  }

  static class Sub extends Super implements Serializable {
    public Sub(int a) {
      super(a);
    }
  }

  public static void main(String[] args) throws Exception {
    Sub sub = new Sub(2);
    ObjectOutputStream test = new ObjectOutputStream(new FileOutputStream("/tmp/test"));
    test.writeObject(sub);

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/tmp/test"));
    Sub sub2 = (Sub) ois.readObject();
    System.out.println(sub2.a);
  }
}

To fix the issue, Super should implement the Serializable interface. Below is an example:

class Super extends Serializable {}
class Sub extends Super {}