Java对象序列化 - 如何添加成员变量?

时间:2014-05-07 15:37:05

标签: java serialization object-serialization

我有一个对象数组,我可以读取和写入磁盘。但现在我想在我的班级中添加一个成员变量。如果我添加成员变量,我将得到类不兼容的错误,并且我无法读取我的序列化对象。有没有办法修改用于序列化的类的成员变量而不会失去读取持久化对象的能力...或者将持久化对象转换为新类的简单方法?

5 个答案:

答案 0 :(得分:2)

首先,Java序列化不适用于对象持久性,因为您遇到了突出问题。

但是有一种解决方法(可以让你在短期内进行) - 向你的类中添加serialVersionUID,并且在以影响其序列化形式的方式修改类时不要更改。

这就是imho,滥用serialVersionUID但会修复你的问题,允许你添加和删除字段,代价是如果不同的JVM使用不同版本的类,你的系统可能会变脆(有办法)除了增加@ EJP答案中链接中详述的serialVersionUID之外,还要处理此事项,因为字段设置为默认值,这意味着当结果不是用户期望的结果并且您有一个比序列化错误更难找到的微妙错误。

所有类都获得serialVersionUID - 如果您尚未声明,则由序列化运行时生成一个。通过声明serialVersionUID告诉序列化运行时,不要生成一个,因为您知道类的序列化形式与之前构建的类兼容,例如,如果您之后添加了toString方法初始编译需要重建或已采取措施确保不同版本正确序列化(同样,@ EJP答案中的链接)。

答案 1 :(得分:2)

来自SO的

This post应该回答你的问题。它甚至解释了如何找到由编译器自动创建的串行版本,如果你没有指定它(在引用的页面中找到serialver)。旧文章仍然很有趣...... 简而言之就是不耐烦:

  • 序列化自动处理新的或删除的成员,前提是serialversion不会更改
  • IDE或JDK的serialver工具可以为您提供编译器自动生成的串行版本(如果您没有指定)

所以你必须找到这个serialversion,添加魔术字段static final long serialVersionUID = xx,因为你只是添加一个成员变量,所以应该没问题。

(引用的帖子是谷歌首次回答java serialization multiple versions

答案 2 :(得分:2)

  

如果我添加成员变量,我将收到类不兼容的错误。

除非你忘了为班级定义serialVersionUID值,否则你不会赢。如果您这样做,请使用该类的原始版本上的serialver实用程序来告诉您要添加的内容。

向可序列化类添加字段完全是良性的。有关在类序列化中断开兼容性之前可以对类执行的操作的完整详细信息,请参阅Versioning chapter of the Object Serialization Specification

答案 3 :(得分:0)

添加类变量后,确保发送方和接收方都具有此类的新版本,它们正在序列化/反序列化。这应该可以解决你的问题。

当然,还要重新生成磁盘/序列化数据。

答案 4 :(得分:-1)

只需填写,增加serialVersionUID是一个很好的做法。序列化使用它来确保两端的类相同,并且保存的数据与当前类兼容。

====

在查看了一些评论之后,我想补充一下为什么serialVersionUID可能是一件坏事。底线,必须手动维护。在拥有强大程序的商店中,这不是问题。但是,只需添加一个然后忽略它或者将其更新一半就会导致错误的安全感。它似乎有所帮助,但事实并非如此。

以下是一些想法:

  • 如果Serialiable类没有serialVersionUID,编译器会发出警告,因此请添加一个。允许警告累积会使它们变得无用。
  • 创建标准然后关注它。选择不更新该值是有效的,但这意味着您必须找到另一种方法来保持系统之间的类匹配。
  • 如果您不打算在类属性更改时更新值,请将值设置为-1作为指示符。