Reputation: 609
I am trying to deserialize a class which is implementing the serializable interface and extending the class which is not serializable.
/**
*
*/
package com.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerializationTest implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1324438308227634614L;
class Papa{
Papa(){
System.out.println("Papa called..");
}
}
class Student extends Papa implements Serializable{
/**
*
*/
private static final long serialVersionUID = 8667392485783922740L;
String name;
int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
*
*/
public Student() {
System.out.println("Constructor called");
}
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
Student arvind = new SerializationTest().new Student();
arvind.setName("Arvind");
arvind.setId(123);
serialize(arvind);
System.out.println("Serialization done..");
deserialize();
}
/**
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*
*/
private static void deserialize() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("tests.txt"));
Student arvind = (Student)ois.readObject();
System.out.println("Deserialize name - " + arvind.getName());
System.out.println(arvind.getId());
ois.close();
}
/**
* @param arvind
* @throws IOException
* @throws FileNotFoundException
*/
private static void serialize(Student arvind) throws IOException, FileNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tests.txt"));
oos.writeObject(arvind);
oos.flush();
oos.close();
}
}
I am getting the below exception -
Exception in thread "main" java.io.InvalidClassException: com.test.SerializationTest$Student; no valid constructor
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(Unknown Source)
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 com.test.SerializationTest.desseialize(SerializationTest.java:88)
at com.test.SerializationTest.main(SerializationTest.java:75)
I have followed the answer of java.io.InvalidClassException: no valid constructor by making the default constructor but it also did not help.
Any suggestion, help is much appreciated.
Upvotes: 0
Views: 1612
Reputation:
All you need is to make both Student and Papa public classes in separate files, or make them both static like this.
static class Papa{
Papa(){
System.out.println("Papa called..");
}
}
static class Student extends Papa implements Serializable{
/**
*
*/
private static final long serialVersionUID = 8667392485783922740L;
String name;
int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
*
*/
public Student() {
System.out.println("Constructor called");
}
}
The reason your code it's not working is that the constructor of inner Papa class cannot be called directly within the constructor of the class Student. We have made Papa static to get rid of this bound.
Upvotes: 1
Reputation: 2262
You need to make the parent class Serializable too.
So your code will be:
class Papa implements Serializable {
Papa(){
System.out.println("Papa called..");
}
}
Also remember that
Serializable class should have an accessible (public or protected) no-args constructor so that the serialization reflection mechanism can create an instance of the class.
See docs for more details:
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
Upvotes: 0