A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

近来发现很多马友提了很多关于序列化的问题,于是我也赶紧收集资料补充一把,可很多知识点还是云山雾罩。查阅JDK文档,接口 Serializable下,发现有一个serialVersionUID 版本号的东西,这是个什么东西?它在实际中有什么作用呢?

1 个回复

倒序浏览
Serializable是一个标志性接口,没有任何成员变量和方法。需要序列化一个类时只需要声明实现这个接口即可。 当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个
     提示功能告诉你去定义 。如果你没有考虑到兼容性可以把它关掉,不管怎样Eclipse都会给你warning提示,这个serialVersionUID为了让该类别Serializable向后兼容。
它的作用是序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。即是保持兼容性。
在进行对象序列化和反序列化的时候,对于不同JDK版本,会出现版本兼容问题。
|-  如:在JDK1.5序列化的对象,在JDK1.0上面可能就不能使用了。
  |-  为了解决对象的序列化和反序列化间的版本不统一问题,引入了一个类常量。
  |-  static final long serialVersionUID
    |-  在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应的类的SerialVersionUID比较
    |-  如果相同 则就认为版本一致 因此可以进行反序列化。
    |-  如果不相同 则就认为版本不一致 然后就抛“序列化版本不一致”异常。
  
如果类A中组合了类B的对象的化,序列化类A对象的同时会序列化类B对象,前提是类A和类B都实现了Serializable接口。
如果类B继承类A,那么序列化类B分为下面两中情况:
1)类A没有实现Serializable接口,而类B实现了。那么根据JavaAPI中的说明,如果需要序列化类B,需要保证类A和类B都有无参的构造方法,如果无法默认构造,则必须显式声明。没有无参构造方法的话,在运行时会报异常。 用这种方式试了一下,虽然可以序列化类A继承来的属性(public、protected、包访问),但是不能正确读取,读出来是null,类B自身特有的属性没问题。有待进一步验证。
2)类A实现了Serializable接口(类B实不实现无所谓,因为继承类A)。通过类B给继承于类A的变量和自身特有的变量赋值,并进行序列化。序列化成功,并可以正确读取。
serialVersionUID用于可序列化类的版本控制。如果不显式的声明一个serialVersionUID,JVM会基于这个序列化类的不同方面特征自动生成一个。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马