zoukankan      html  css  js  c++  java
  • 关于实现序列化的类提示没有定义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 的预设值。这就是你引用的文章所描述的事情。

  • 相关阅读:
    C# ListView应用
    C# 使用System.Speech 进行语音播报和识别
    支付宝支付-扫码支付详解
    使用git提交项目到码云
    C# byte[]数组和string的互相转化 (四种方法)
    C#中字节数组byte[]、图片image、流stream,字符串string、内存流MemoryStream、文件file,之间的转换
    C# 结构体和List<T>类型数据转Json数据保存和读取
    对 JSON 数据进行序列化和反序列化
    win10与虚拟机fedora14使用samba文件共享
    serialVersionUID, ObjectInputStream与ObjectOutputStream类,Serializable接口,serialVersionUID的作用和用法
  • 原文地址:https://www.cnblogs.com/oisiv/p/384426.html
Copyright © 2011-2022 走看看