private static final long serialVersionUID的作用

今天在看项目源码的时候发现struts的action里面有

private static final long serialVersionUID = -1672970955045193907L;

这样的一条语句。

中文搜索之后,全部都是

如果你修改了此类, 要修改此值。否则以前用老版本的类序列化的类恢复时会出错。为了在反序列化时,确保类版本的兼容性,最好在每个要序列化的类中加入private static final long serialVersionUID这个属性,具体数值自己定义。

中文的全部都是抄来抄去的答案。这真是叫人恶心。

有趣的事,在外国网站也出现了这样的状况。原帖:http://www.coderanch.com/t/596397/java/java/private-static-final-long-serialVersionUID

What is private static final long serialVersionUID = 1L; ???

上面那句话是什么?

Hi Friends,

Can you please tell me the purpose of this line ???

朋友们,

谁能告诉我这段代码的缘由?

SerialVersionUID is an ID which is stamped on object when it get serialized usually hashcode of object, you can use tool serialver to see serialVersionUID of a serialized object . SerialVersionUID is used for version control of object. you can specify serialVersionUID
in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object
will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch.

SerialVersionUID,后面简称SUID,是当对象序列化的时候对象的一个标识(stamp on 在这里我也不太清楚翻译成什么好),SUID的值常为该对象的hascode。你可以使用工具serialver查看一个序列化对象的SUID。SUID用于控制对象的版本。你也可以在类文件中指定SUID。不指定SUID的结果就是当你添加或者更改类的域并已经序列化类的时候,类是不能再恢复了,因为新的SUID和之前的SUID不同了。Java的序列化过程依赖于正确的SUID来反序列化已经序列化的对象,如果SUID不匹配,那么就会抛
java.io.InvalidClassException 异常了。

Please don’t simply copy and paste from another website; that may be breach of copyright. That quote is confusing at the best.

An SUID is not a hash of the object, but a hash of its originating class. If the class is updated, for example with different fields, the SUID can change. You have four (at least) possible courses of action:-

  • 1: Leave out the SUID. This tells the runtime that there are no differences between versions of classes when serialising and deserialising.
  • 2: Always write a default SUID, which looks like the heading of this thread. That tells the JVM that all versions with this SUID count as the same version.
  • 3: Copy an SUID from a previous version of the class. That tells the runtime that this version and the version the SUID came from are to be treated as the same version.
  • 4: Use a generated SUID for each version of the class. If the SUID is different in a new version of the class, that tells the runtime that the two versions are different and serialised instances of the old class cannot be deserialised
    as instances of the new class.

    请不用简单地从别的网站复制粘贴(一针见血指出上面回答的缺点);这是对版权的破坏,而且这样的描述最多还是困惑读者。

    SUID不是一个对象的哈希值(翻译错了,公司一个牛逼同事提醒了!),是源类的哈希值。如果类更新,例如域的改变,SUID会变化,这里有4个步骤:

    1.忽略SUID,相当于运行期间类的版本上的序列化和反序列上面没有差异。

    2.写一个默认的SUID,这就好像线程头部。告诉JVM所有版本中有着同样SUID的都是同一个版本。

    3.复制之前版本类的SUID。运行期间这个版本和之前版本是一样的版本。

    4.使用类每个版本生成的SUID。如果SUID与新版本的类不同,那么运行期间两个版本是不同的,并且老版本类序列化后的实例并不可以反序列成新的类的实例。

    第四点才是private static final long serialVersionUID的作用的重点所在。

    Thanks Campbell, will be careful from now on.

    后面那个直接抄答案的跟上面那位答者致谢。对方也在后面的回复中也竖起大拇指。

    最后总结一下:其实序列化的作用是能转化成Byte流,然后又能反序列化成原始的类。能在网络进行传输,也可以保存在磁盘中,有了SUID之后,那么如果序列化的类已经保存了在本地中,中途你更改了类后,SUID变了,那么反序列化的时候就不会变成原始的类了,还会抛异常,主要就是用于版本控制。

    这完完全全是和国内这种复制粘贴漫天飞的问答的不同的格调,这正是技术所需要的一种气氛,一种对更好的答案的追求。

    希望以后国内的技术氛围也能如此!

  • 时间: 2024-11-05 13:34:06

    private static final long serialVersionUID的作用的相关文章

    private static final long serialVersionUID = 1L;

    作者:郭无心链接:https://www.zhihu.com/question/24852886/answer/117314768来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 其实答主想问的是serialVersionUID的作用. 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的. 在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionU

    private static final long serialVersionUID = 1L;详解

    public class User implements Serializable { /** * serialVersionUID */ private static final long serialVersionUID = 1L; /** * 主键ID */ private Integer userId; /** * 用户名 */ private String userName; /** * 密码 */ private String passWord; /** * 姓名 */ privat

    创建servlet类时出现的“private static final long serialVersionUID = 1L;”语句是什么意思啊?

    实现java.io.Serializable这个接口是为序列化,serialVersionUID 用来表明实现序列化类的不同版本间的兼容性.如果你修改了此类, 要修改此值. 否则以前用老版本的类序列化的类恢复时会出错. 实现后如果你用的是工具的话会出来警告,他会提示你,可以自动生成private static final long serialVersionUID = 1L; 为了在反序列化时, 确保类版本的兼容性,最好在每个要序列化的类中加入private static final long

    private static final long serialVersionUID = 1L用来表明类的不同版本间的兼容性

    Java中serialVersionUID的解释 serialVersionUID作用: 相当于java类的身份证.主要用于版本控制.serialVersionUID作用是序列化时保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.有两种生成方式: 一个是默认的1L,比如:private static final long serialVersionUID = 1L; 一个是根据类名.接口名.成员方法及属性等来生成

    困扰你的private static final long serialVersionUID

    很多时候一个新手在写代码的时候,往往你的IDE就会告诉你一个警告 然后你点击处理这个警告之后,它就会默认给你的类生成一个 private static final long serialVersionUID = 1L; 然后强迫症的孩子就一直不明白为什么会需要这个东西,这个东西到底是干嘛用得呢? 然后渐渐的你会发现,这个东西和你写的代码毫无关系,没什么卵用,于是渐渐的你就把他扔在一边了. 这次我就需要来解决这个问题,困扰你的private static final long serialVers

    JavaBeans 中添加 private static final long serialVersionUID = 1L

    这个东西是用来serialization 的key,A和B相互之间传输信息,用seralize,但是相互之间把解包之后的文件进行了更改,如果你程序中不加这个,相互之间再传输,会因为这个key不一样,而失败.所以,在程序中定义,会使软件版本兼容,无论怎么改,都可以相互序列化和反序列化. Java中,如果class实现了序列化接口,你没有加这一行,eclipse会自动给warning,建议加上,否则,JVM会自动编译生成一个序列号,这样传输会造成反序列化失败.因为不同的JVM之间的序列化算法是不一样

    浅析java修饰符之public default protected private static final abstract

    浅析java修饰符之public default protected private static final abstract 一   修饰符的作用:用来定义类.方法或者变量,通常放在语句的最前端 二   分类(大致分两类) 1.访问修饰符,包括:public default protected private 2.非访问修饰符,包括:static final abstract 三 访问修饰符--Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java支持4种不同的访问权

    PowerMockito模拟private static final类变量

    mock模拟private static final now=system.currentmills; 首先在测试类开头加上: @prepareForTest({System.class}) Class A{ } 然后,在方法上添加:powermockito.mockstatic(system.class);powermockito.when(system.currentmills).thenreturn(now);system.currentmills; 如果要mock模拟类的变量Class

    Eclipse警告: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. 当你