[Java SE/序列化] Java可序列化的实体类`serialVersionUID`的作用

概述: Serializable接口、序列化与反序列化

  • 实现Java Serializable接口的目的为类可持久化(如:网络传输或本地存储),为系统的分布和异构部署提供先决条件

若没有序列化,现在我们所熟悉的远程调用对象数据库都不可能存在,

  • serialVersionUID适用于java序列化机制

简单来说,JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。
在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。
如果相同,说明是一致的,可以进行反序列化,否则,会出现反序列化版本一致的异常,即是InvalidCastException

  • 具体序列化的过程
  • 序列化操作时会把系统当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会自动检测文件中的serialVersionUID,判断它是否与当前类中的serialVersionUID一致。
  • 如果一致说明序列化文件的版本与当前类的版本是一样的,可以反序列化成功,否则就失败;
  • serialVersionUID有2种显示的生成方式:
  • 方式1:默认的1L。

比如:private static final long serialVersionUID = 1L;

  • 方式2:根据包名,类名,继承关系,非私有的方法和属性,及参数,返回值等诸多因子计算得出的,极度复杂生成的一个64位的哈希字段。

基本上计算出来的这个值是唯一的。
比如:private static final long serialVersionUID = xxxxL;

注意:显式声明serialVersionUID可以避免对象不一致,当一个类实现类Serializable接口,如果没有显示定义serialVersionUID时,Eclipse等IDE会自动给出相应的提醒;
面对这种情况,我们只需要在Eclipse中点击类的warning图标,Eclipse就会自动给出两种生成方式。
如果不想定义,在Eclipse的设置中也可以把它关掉的,设置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems
Serializable class without serialVersionUIDwarning改成ignore即可。

  • 当实现java.io.Serializable接口中没有显示的定义serialVersionUID变量时,JAVA序列化机制会根据Class自动生成一个serialVersionUID作序列化版本比较用。

这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。

  • 如果我们不希望通过编译强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,就需要显示的定义一个serialVersionUID,类型为long的变量。

不修改这个变量值的序列化实体,都可以相互进行序列化反序列化

X 参考文献

posted @ 2025-03-19 17:52  千千寰宇  阅读(86)  评论(0)    收藏  举报