Java 反序列化时发生异常
我试图反序列化一个实现可序列化接口的类,并扩展不可序列化的类Java 反序列化时发生异常,java,exception,serialization,deserialization,Java,Exception,Serialization,Deserialization,我试图反序列化一个实现可序列化接口的类,并扩展不可序列化的类 /** * */ 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.ObjectOutp
/**
*
*/
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();
}
}
我得到以下例外情况-
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)
我按照的答案创建了默认构造函数,但它也没有帮助
非常感谢您的建议和帮助。您还需要使父类可序列化 因此,您的代码将是:
class Papa implements Serializable {
Papa(){
System.out.println("Papa called..");
}
}
还记得吗
可序列化类应具有可访问(公共或受保护)的无参数构造函数,以便序列化反射机制可以创建该类的实例
有关更多详细信息,请参阅:
在反序列化过程中,不可序列化类的字段将
使用的public或protected no arg构造函数初始化
班级。不带参数的构造函数必须可被指定的子类访问
可序列化。可序列化子类的字段将被还原
从小溪里
您所需要的只是将Student和Papa公共类都放在单独的文件中,或者像这样使它们都是静态的
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");
}
}
代码不起作用的原因是内部Papa类的构造函数不能在Student类的构造函数中直接调用。我们已经将Papa设置为静态,以摆脱这种束缚。请将类设置为
Papa
和Student
静态内部类。现在它们是常见的内部类,如果不创建SerializationTest
的实例,就无法创建它们的实例。感谢Ivan的快速响应。是的,当两个类都被标记为static或者只有Papa
类被标记为static时,它才起作用,但是我想了解使父类Papa
静态的背后的逻辑是什么?为什么它不能非静态工作?谢谢Eugen的回复!!是的,当两个类都被标记为static或者只有Papa类被标记为static时,它是有效的,但是我想了解使父类Papa为static背后的逻辑是什么?为什么它不以非静态方式工作?太好了!!关键是。。。现在有道理了。。谢谢@Eugen