我将对象序列化为SQLiteOpenHelper中的blob,如下所示:
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(value);
out.close();
每个类定义自己永远不会改变的serialVersionUID。
序列化/反序列化实际上如何工作?它是否记住了字段的名称以及与之关联的值?如果我继续添加/删除字段,是否有可能现有字段的值已修改?
例如,让我们说我序列化了这个类:
public class Foo implements Serializable {
private static final long serialVersionUID = 4068188167994381987L;
String x;
int y;
}
Where x is "A", and y is 1;
然后我像这样修改类:
public class Foo implements Serializable {
private static final long serialVersionUID = 4068188167994381987L;
float f;
String x;
}
如果我继续添加/删除字段,每次我反序列化Foo
x仍然是" A"?
答案 0 :(得分:3)
您无法删除字段。有关Serializable
课程的兼容更改,请参阅here at Oracle。
是的,在课程Foo
发生更改后,旧版Foo
的反序列化会将x设置为“A”,但由于您删除了某个字段,因此无效。
我建议保留旧字段y
并将其标记为@deprecated
:
public class Foo implements Serializable {
private static final long serialVersionUID = 4068188167994381987L;
String x;
float f;
@deprecated int y;
}
答案 1 :(得分:1)
不,如果更改字段顺序或字段类型,则反序列化将无法正常工作。它会导致异常或读取不正确的数据。
这就是为什么每次进行更改时都建议更改serialVersionUID,以便更改类的序列化格式。
如果要在不破坏序列化的情况下灵活更改类内部,则应使用Externalizable接口。
答案 2 :(得分:0)
我会使用“magic”序列化方法writeObject和readObject来定义自定义序列化流。这样,你的类的新版本可以读取旧格式,并根据一些转换算法填充新字段(这里,读取y int并根据它设置f的值)。
有关序列化“魔术”方法的更多信息,请参见此处: http://thecodersbreakfast.net/index.php?post/2011/05/12/Serialization-and-magic-methods