反序列化的工作原理是什么?

时间:2014-01-07 07:28:57

标签: java serialization deserialization

据我所知,没有调用Object的序列化类的构造函数,而是第一个非序列化构造函数的no-arg构造函数。现在考虑以下代码

public class SerializeDemo implements Serializable {

private String name;
int age;    //default 0

public SerializeDemo(String name, boolean setAge){
    this.name = name;
    if(setAge){
        this.age = 18;
    }
}

@Override
public String toString() {
    return "Name is " + name + " and age is " + age;
}

public static void main(String args[]) throws IOException, ClassNotFoundException {

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
    SerializeDemo sd = new SerializeDemo("Test",true);
    System.out.println("Before Serialization : " + sd);
    oos.writeObject(sd);
    SerializeDemo sdCopy = (SerializeDemo)ois.readObject();
    System.out.println("After Deserialization : " + sdCopy);
}
}

并且输出是(如预期的那样)

Before Serialization : Name is Test and age is 18
After Deserialization : Name is Test and age is 18

现在,具有no-arg构造函数的非可序列化超类是Object(如果我错了,请纠正我)。所以基本上没有调用SerializeDemo构造函数。

现在,在反序列化期间创建Object时,它将尝试重建实例状态。所以它将年龄定为18岁。

问题是怎么回事?

我故意不提供制定者。也不是按照上面的讨论,它的构造函数被调用。那么它是如何设置的?(同样适用于名称)

2 个答案:

答案 0 :(得分:4)

  

现在,具有no-arg构造函数的非序列化超类是Object。

正确。

  

所以基本上没有调用SerializeDemo构造函数。

正确。

  

现在,在反序列化期间创建Object时,它将尝试重建实例状态。所以它将年龄定为18岁。

正确。

  

问题是怎么回事?

反思...关闭访问权限检查。

序列化类中的类描述符给出了所有序列化字段的名称和类型。 Class对象为实际类定义Field个对象。反序列化代码将可用的序列化字段与Field对象匹配,然后使用Field.set(...)方法设置字段值。

(事实上,这是一个实现细节,但这是我对当前一代JVM中它如何工作的理解。你总是可以检查源代码......)

答案 1 :(得分:2)

您可以查看ObjectInputStream源代码。它使用反射,它创建一个对象,从流中读取字段,并使用反射设置对象的字段。您可以在调试器中运行代码,然后一步一步地完成设置年龄的行。