如果我序列化一个类对象并稍后修改了一个字段并将该字段移动到Parent类,会发生什么?

时间:2016-03-09 06:25:03

标签: java serialization deserialization

我有一个类Object并保留它。现在我想创建现有类的超类并将一个字段移动到父类。

当我反序列化对象时,它将该字段值赋予null。

A PHP Error was encountered

Severity: Warning

Message: dir(https://www.domain.com/pdfs/bob/uploaded): failed to open dir: not implemented

Filename: views/search.php

Line Number: 71

我坚持这个类对象。

我创建了新课程。

Class A{
int a;
String b;
}

我将B类扩展为A。

Class B{
String b;
}

现在当我想反序列化现有的存储对象时,它将b字段值设为null;

3 个答案:

答案 0 :(得分:2)

如果在旧版本的序列化实例中对类进行重大更改,则会发生各种不良事件。

在这种情况下,您在表示级别进行了不兼容的更改,但(实际上)告诉序列化系统旧的和新的表示是兼容的...因为您在旧的表达式中使用相同的serialVersionUID值该课程的新版本。

我也猜测,当类A(子类)实现Serializable时,类B(超类)不会。当可序列化类具有不可序列化的超类时,超类的字段不会被序列化。当类被反序列化时,将调用非可序列化的超类no-args构造函数。在您的示例中,B构造函数必须将字段b初始化(或默认初始化)为null

通过序列化获得正确的版本是很棘手的。如果您正在考虑对可序列化类进行更改并且您希望能够使用以前的序列化对象,那么您应该仔细阅读对象序列化规范的Chapter 5。事实上,你应该阅读整个规范。

一般情况下,如果有可能需要进一步发展可序列化类,Java对象序列化不是一个好的选择。基于文本的序列化方案(如JSON或XML)更健壮,更“宽容”。或者,数据库可能是更好的选择。

答案 1 :(得分:0)

遗憾的是,Java的序列化API不是为代码的这种更改而设计的。如果您要进行此类更改,我建议您序列化为JSON或其他内容。它的工作量更大,但我认为它值得进行未来验证。

答案 2 :(得分:0)

  

当我想反序列化现有的存储对象时,它将b字段值赋予null;

这种行为是正确的。您已向父级添加了一个字段,并从该子级中删除了一个字段。添加的字段从不包含它们的流中反序列化为null,并且在包含它们的流中遇到删除的字段时将被忽略。

您需要阅读对象序列化规范的Versioning of Serializable Objects章节。