• 关于Serializable的serialVersionUID


      在实现了Serializable接口的class中,需要声明一个long serialVersionUID,用来标明当前class的版本号,但很多人在编程时,总是不原意去声明这个serialVersionUID,又JVM自己来生成。下面来看看serialVersionUID的作用:

    1、如果在序列化写 时的版本号和序列化读 时的版本号,不一致,将会有异常:java.io.InvalidClassException:local class incompatible: stream classdesc serialVersionUID = …, local class serialVersionUID = …

    2、那如果在class中不声明这个属性呢?那结果可以就会变得比较诡异了: 

    1)、在序列化写 的时候,虚拟机A会为它计算出一个serialVersionUID,计算的方法是依据class的信息,再具体我也不清楚了。

    2)、在序列化读 的时候,虚拟机B也会为class计算出一个serialVersionUID,然后做比较。

    3)、那么如果两个虚拟机是不同类型的虚拟机,那么计算方法可能就不一样了,于是即使相同的classserialVersionUID也可能会不同,不同的class的,理论上来说,也存在serialVersionUID相同的可能性,所以,serialVersionUID尽量由我们自己来指定,而不要由虚拟机来计算。

    3、那如果serialVersionUID一致,而class发生了变化呢? 

    1)、如果虚拟机A中的AClass有一个属性,而虚拟机B中的AClass,没有这个属性,那么这个属性将被忽略,而不会有异常。

    2)、如果虚拟机A中的AClass没有的属性,而在虚拟机B中多出来的属性,那么这个属性将被赋予一个缺省值,而不会有异常。

    3)、如果虚拟机A中的AClass有一个属性,在虚拟机B中的AClass也有这个属性,但这个属性的类型变了,比如说int变成了long,抑或其他的变化,将会有异常:java.io.InvalidClassException:incompatible types for field …

    经过序列化而产生的异常都是 java.io.InvalidClassException,不会产生java.lang.ClassCastException,两者还是有比较大的区别的,从名字上就可以看得出来。

    看完你还会让JVM自己来生成serialVersionUID吗?你还加@SuppressWarnings("serial")吗?在一个单机上或许看不出什么问题,但在分布式计算、或者你需要提供jar供别人使用的时候,这个问题就会暴露。

  • 相关阅读:
    码云安装SSH私钥步骤
    关于在Python3中:字典在迭代过程中,字典的长度是不允许改变的
    Selenium ChromeDriver与Chrome版本映射表(更新到v78)
    web driver下载地址(selenium-3.141_浏览器版本对应)
    Python报错pip超时
    LoginRequiredMixin类
    pycharm断点调试django
    js克隆
    索引
    java8date
  • 原文地址:https://www.cnblogs.com/haimishasha/p/5058085.html
Copyright © 2020-2023  润新知