关于实现序列化的类提示没有定义serialVersionUID域

轉自http://iamin.blogdriver.com/iamin/1139925.html

The serializable class XXX does not declare a static final serialVersionUID field of type long

serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。

你可以随便写一个,在Eclipse中它替你生成一个,有两种生成方式:
一个是默认的1L,比如:private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:private static final long serialVersionUID = -8940196742313994740L;之类的。

当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个提示功能告诉你去定义之。
在Eclipse中点击类中warning的图标一下,Eclipse就会自动给定两种生成的方式,如上面所述。如果不想定义它,在Eclipse的设置中也可以把它关掉的,设置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems
将Serializable class without serialVersionUID的warning改成ignore即可。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入serialVersionUID,Eclipse都会给你warning提示,这个serialVersionUID为了让该类别Serializable向后兼容。

如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,这个可以避开不兼容性的问题。

-------------------end.


另外的说法
1.
有直接或间接实做 Serializable 的介面的 class 需要(才有意义) serialVersionUID field。这个 field 会影响 JRE 内建的 serialization 机制,当你写一个 class foo,你曾经把 instance serialize 到磁碟,之后你改变了 class foo 的实做(比如多了一个 field),接着你再把之前存下来的 serialized form data 拿来 deserialize 成 class foo instance 就会失败,除非 class foo 定义的 serialVersionUID 没有变化(此情况下 deserialize 时,新增的 field 会是初始值 depend on type)。

一开始就说过了,serialVersionUID 跟 serialization 有关,如果你写的 class(bas on Exception) 根本没有做 serialization 的必要(需求),那么有没有 serialVersionUID 就完全感觉不出来。

在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID,对于Test.class,执行命令:serialver Test。

2.你可以使用 JDK tool: serialver 来取得一个 class 的 serialVersionUID(如果 class 没有定义 serialVersionUID,会帮你求得一个)。在 runtime 也可以用 java.io.ObjectStreamClass 来取得 class 的 serialVersionUID(无论该 class 有没有定义 serialVersionUID)。ObjectInputStream/ObjectOutputStream 在做 serializaton 就是会利用到 ObjectStreamClass。

如果你没有自己定义 serialVersionUID 给定其值,JRE 帮你计算出来的 serialVersionUID 会依照 class 的内容不同而不同,如果你没有自订 serialVersionUID,你把此 class instance serialize 到档案,之后你修改过该 class(比如多了一个 field),下一次你想把封存档案 deserialize 成 object 就会失败。自订 serialVersionUID 并保持不变,这样子即使你修改过 class(比如新增一个 field),deserialize 上一次 serialize 封存的档案还是可以的,新增的 field 会是预设值,这预设值并不是指 field 定义时的初始式给定的值(field 初始式实际上是在 constructor 里),而是指该 type 的预设值。这就是你引用的文章所描述的事情。

posted @ 2008-09-25 16:51  wyl232  阅读(602)  评论(0编辑  收藏  举报