当serialVersionUID
丢失时,Eclipse会发出警告。
可序列化的类Foo不声明
类型的静态最终serialVersionUID字段
什么是serialVersionUID
?为什么它很重要?请举一个缺少serialVersionUID
会导致问题的示例。
发布于 2008-11-12 23:30:16
java.io.Serializable
的文档可能是你能得到的最好的解释了:
序列化运行时将一个版本号(称为
serialVersionUID
)与每个可序列化类相关联,该版本号在反序列化期间用于验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。如果接收方为对象加载的类具有与相应发送方的类不同的serialVersionUID
,则反序列化将导致InvalidClassException
。可序列化类可以通过声明名为serialVersionUID
的字段来显式声明其自己的serialVersionUID
,该字段必须是静态的、最终的,并且类型为Java ACCESS-MODIFIER static final long serialVersionUID = 42L;如果可序列化类没有显式声明serialVersionUID
,则序列化运行时将根据该类的各个方面计算该类的默认serialVersionUID
值,如Java对象序列化规范中所述。但是,强烈建议所有可序列化的类显式声明serialVersionUID
值,因为默认的serialVersionUID
计算对类细节高度敏感,这些细节可能因编译器实现而异,因此在反序列化过程中可能会导致意外的InvalidClassExceptions
。因此,为了在不同的java编译器实现中保证一致的serialVersionUID
值,可序列化的类必须声明显式的serialVersionUID
值。还强烈建议显式类声明在可能的情况下使用serialVersionUID
修饰符,因为此类声明仅适用于直接声明的类-serialVersionUID
字段作为继承成员没有用处。
发布于 2008-11-13 04:24:58
如果序列化仅仅是因为必须为了实现而序列化(谁关心是不是为了HTTPSession
而序列化,对于instance...if是不是存储的,您可能并不关心de-serializing
a form对象),那么可以忽略这一点。
如果您实际上正在使用序列化,那么只有当您计划直接使用序列化来存储和检索对象时,它才有意义。serialVersionUID
表示您的类版本,如果您的类的当前版本与以前的版本不向后兼容,则应该递增它。
大多数情况下,您可能不会直接使用序列化。如果是这种情况,请通过单击快速修复选项生成一个默认的SerialVersionUID
,不用担心。
发布于 2008-11-12 23:37:19
我不能错过这个推广Josh Bloch的书Effective Java (第二版)的机会。第10章是关于Java序列化的不可缺少的资源。
根据Josh,自动生成的UID是基于类名、实现的接口以及所有公共和受保护的成员生成的。以任何方式更改其中任何一个都会更改serialVersionUID
。因此,只有当您确定不会有超过一个版本的类被序列化(跨进程或稍后从存储中检索)时,您才不需要弄乱它们。
如果现在忽略它们,后来发现需要以某种方式更改类,但要保持与类的旧版本的兼容性,则可以使用JDK工具串行器在旧类上生成serialVersionUID
,并在新类上显式设置它。(根据您的更改,您可能还需要通过添加writeObject
和readObject
方法来实现自定义序列化-请参阅Serializable
javadoc或前面提到的第10章。)
https://stackoverflow.com/questions/285793
复制相似问题