- Identify the fields that should be serializable (Use the serialPersistentFields member to explicitly declare them serializable or use the transient keyword to denote nonserializable fields.)
- Have access to the no-arg constructor of its first nonserializable superclass
When A is not serializable the Class information or metadata is not stored in the serialized stream. While deserializing the object B it need to construct back object A and I believe java must be using reflection to construct A back. If you look at java.lang.Class api you will see that newInstance() creates new instance by calling no-arg constructor. [Java by default defined no-arg constructors if you haven't defined argumented constructors.]
Apart from this I couldn't think why it requires no-arg constructor to be defined in non-serialized super class. If there is other reasons for no-arg constructor requirement in non-serialized supper class it will be great to know.
Purushothaman is right. When objects are deserialized, their constructors are not run. The exceptions to that rule are if something is a non-serializable object referenced as an instance variable in a serializable class, or if a serializable class has a non-serializable class in its class hierachy. The latter is what we have in your example. B is serializable, but A is not. B's constructor will not be run, but we need a constructor for A.
Since B is serializable, its constructor never gets called and so there isn't an opportunity to pass an argument to A's constructor. To handle instantiating the "A part of B", the JVM needs a no-arg constructor. Since a constructor taking an int is defined, the compiler doesn't provide the no-arg constructor for free so compilation fails. If you change the value passed to A in super (10) so that it doesn't match the default value in A (also 10) and add a no-arg constructor to A, you'll see that B will lose its x value that it inherited from A (it will be returned to its default) if you serialize and deserialize B.
It is possible to serialize and deserialize B and keep the x value inherited from A even if A is not serializable, but you have to override writeObject() (see Serializable) using the defaultWriteObject() and writeInt() methods of ObjectOutputStream and override writeObject() (see Serializable) using the defaultReadObject() and readInt() methods of ObjectInputStream followed by a call to A's single int constructor.