Dal*_*ale 56 java serialization deserialization
我有一个实现Serializable的公共类,它由多个其他类扩展.之前只有那些子类被序列化 - 从来不是超类.
超类定义了一个serialVersionUID.
我不确定它是否重要,但它没有标记为私有,而是它只是默认保护 - 你可能会说它是包保护
static final long serialVersionUID = -7588980448693010399L;
Run Code Online (Sandbox Code Playgroud)
但是,超类或任何子类都实现了readObject或writeObject,并且没有子类具有明确定义的serialVersionUID.我认为超类中定义的一个就足够了.
尽管如此,只要读回以前的序列化对象,直到新的实例变量,List/ArrayList以及新方法被添加到超类中,并且一些私有实例变量被添加到其子类之一,就可以了. .
现在,当尝试读回先前序列化的对象时,会抛出异常.一个类似于此:
com.SomeCompany.SomeSubClass; local class incompatible: stream classdesc serialVersionUID = 1597316331807173261, local class serialVersionUID = -3344057582987646196
Run Code Online (Sandbox Code Playgroud)
我假设这是因为默认的serialVersionUID,因为我没有在任何子类中声明一个而使用,现在由于超类和一个子类的变化而改变了.
关于如何摆脱这种困境的建议将不胜感激.我假设我需要实现readObject和writeObject,但除了调用defaultReadObject()和defaultWriteObject()之外,我不确定我需要做什么.我也不知道是否需要将serialVerisonUID添加到所有子类中,或者是否需要每个子类实现readObject和writeObject,或者我是否可以实现它们一次,假设我需要在超类中完成.
jta*_*orn 45
@DanielChapman给出了serialVersionUID的一个很好的解释,但没有解决方案.解决方案是:serialver
在所有旧类上运行程序.将这些serialVersionUID
值放在当前版本的类中.只要当前类与旧版本串行兼容,您应该没问题.(注意,将来的代码:你应该始终有一个serialVersionUID
对所有 Serializable
班)
如果新版本不是串行兼容的,那么你需要用自定义readObject
实现做一些魔术(writeObject
如果你试图编写与旧代码兼容的新类数据,你只需要一个自定义).一般来说,添加或删除类字段不会使类序列不兼容.通常会改变现有字段的类型.
当然,即使新类是串行兼容的,您仍可能需要自定义readObject
实现.如果你想填写从旧版本的类中保存的数据中缺少的任何新字段,你可能想要这个(例如,你有一个新的List字段,你想在加载旧的类数据时初始化为空列表).
Dan*_*man 30
这里简短的回答是,如果您没有指定序列ID,则通过哈希计算序列ID.(静态成员不是继承的 - 它们是静态的,只有(1)并且它属于类).
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html
getSerialVersionUID方法返回此类的serialVersionUID.请参见第4.6节"流唯一标识符".如果未由类指定,则返回的值是使用国家标准协会定义的安全散列算法(SHA)从类的名称,接口,方法和字段计算的散列.
如果更改类或其层次结构,则哈希值将不同.这是一件好事.您的对象因其成员不同而不同.因此,如果您从序列化形式中读回来,它实际上是一个不同的对象 - 因此是例外.
答案很长,序列化非常有用,但除非没有其他办法,否则可能不应该用于持久化.它是一条危险的道路,特别是因为你正在经历的事情.您应该考虑数据库,XML,文件格式以及纯Java项目的JPA或其他持久性结构.
tax*_*eta 17
对我来说,我忘了添加默认的序列号.
private static final long serialVersionUID = 1L;
Run Code Online (Sandbox Code Playgroud)
这对我有用:
如果您将Serialized类对象写入文件,然后对文件进行一些更改并对其进行编译,然后尝试读取对象,则会发生这种情况.
因此,如果修改并重新编译类,则再次将必要的对象写入文件.
PS:这不是解决方案; 本来是一个解决方法.
归档时间: |
|
查看次数: |
130669 次 |
最近记录: |