反序列化时出现异常

时间:2018-02-10 20:35:04

标签: 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.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)

我通过制作默认构造函数来遵循java.io.InvalidClassException: no valid constructor的答案,但它也没有帮助。

任何建议,帮助都非常感谢。

2 个答案:

答案 0 :(得分:1)

您所需要的只是将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静态摆脱这种束缚。

答案 1 :(得分:0)

您还需要创建父类Serializable。

所以你的代码将是:

class Papa implements Serializable {
         Papa(){
            System.out.println("Papa called..");
        }
}

还要记住

Serializable类应该具有可访问(公共或受保护)的no-args构造函数,以便序列化反射机制可以创建类的实例。

有关详细信息,请参阅docs

  

在反序列化期间,非序列化类的字段将是   使用公共或受保护的无参数构造函数初始化   类。必须可以访问子类的无参数构造函数   序列化。将恢复可序列化子类的字段   来自溪流。