反序列化的工作原理如何?

据我所知,没有调用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岁。

问题是怎么样的?

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

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

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

正确。

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

正确。

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

正确。

问题是怎么样的?

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

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

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