after reading for serialization, i tried to perform an experiment on the example provided in the book. Following code has some variation and this is basically picked from SCJP book.
import java.io.FileInputStream;
public class SerializationTest {
public static void main(String[] args) {
Collar c = new Collar(4);
Dog d = new Dog(c, "Sheru", 32);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(
"C:\\Users\\dell\\Desktop\\NewDir\\DogState.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(d);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// ***************************************************************************************************
// //
Dog restore = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(
"C:\\Users\\dell\\Desktop\\NewDir\\DogState.txt");
ois = new ObjectInputStream(fis);
restore = (Dog) ois.readObject();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
fis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("after: dog name: "+ restore.name +" , collar=" + restore.getCollar());
System.out.println("Animal material is:" + restore.getWeight());
}
}
// Intentionally added parameterized constructor so that default constructor is not called.
class Animal{
int weight = 42;
public Animal(int weight) {
this.weight = weight;
System.out.println("animal constructor");
}
}
class Dog extends Animal implements Serializable {
String name;
transient Collar collar;
public Collar getCollar() {
return collar;
}
public void setCollar(Collar collar) {
this.collar = collar;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Dog(Collar collar, String name, int weight) {
super(weight);
System.out.println("Dog constructor");
this.collar = collar;
this.name = name;
}
}
class Collar {
int size;
public Collar(int size) {
System.out.println("Collar constructor");
this.size = size;
}
}
Here my question is why InvalidClassException is occuring, Please explain what is the root cause of exception. Current output is
Collar constructor
animal constructor
Dog constructor
java.io.InvalidClassException: Dog; Dog; no valid constructor
at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at SerializationTest.main(SerializationTest.java:39)
Caused by: java.io.InvalidClassException: Dog; no valid constructor
at java.io.ObjectStreamClass.<init>(Unknown Source)
at java.io.ObjectStreamClass.lookup(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at SerializationTest.main(SerializationTest.java:18)
Exception in thread "main" java.lang.NullPointerException
at SerializationTest.main(SerializationTest.java:54)
If i remove Animal constructor and comment out the super(weight) in Dog constructor, then output is
Collar constructor
Dog constructor
after: dog name: Sheru , collar=null
Animal material is:42
I understand this output, and i also get the fact that during de-serialization serialzable class's superclass constructor is called but here no default constructor is present, so exception occured. But why this exception occur i want to know.