咱们有时候在写代码的时候,对于一个须要序列化的类,如果不去写 serialVersionUID
,编译器可能就会提醒咱们 The serializable class ClassName does not declare a static final serialVersionUID field of type long
。
有应用过 MyBatis-plus 框架的同学应该也发现,在应用反向代码生成时,所生成的实体类也都带有 static
final
进行润饰的 long
类型 serialVersionUID
。那么到底 serialVersionUID 是什么呢?有什么用?
附官网文档连贯:https://docs.oracle.com/javas...
它是什么?
简略概括而言, serialVersionUID
是用于在序列化和反序列化过程中进行核验的一个版本号。
序列化运行时将一个版本号(称为serialVersionUID
)与每个可序列化类相关联,该版本号在反序列化期间用于验证序列化对象的发送方和接管方是否为该对象加载了与序列化兼容的类。
如果接管方为对象加载的类与相应发送方类的serialVersionId
不同,则反序列化将导致InvalidClassException
。
可序列化类能够通过申明名为 serialVersionUID
的字段显式申明本人的 serialVersionUID
,且该字段必须是static
、final
的且类型为long
:
ANY-ACCESS-MODIFIER static final long serialVersionUID=42L;
不申明会怎么?
如Java(TM)对象序列化标准中所讲述的,如果可序列化类没有显式申明serialVersionUID
,则序列化运行时将依据类的各个方面计算该类的默认serialVersionUID
值。
然而,强烈建议所有可序列化类显式申明serialVersionUID
值,因为默认的 serialVersionUID
计算对类详细信息高度敏感,这些详细信息可能因编译器实现而异,因而在反序列化过程中可能会导致意外的InvalidClassExceptions
。
因而,为了保障在不同的java编译器实现中SerialVersionId
值是统一的,可序列化类必须申明一个显式的SerialVersionId
值。还强烈建议显式 serialVersionUID
申明尽可能应用 private
修饰符,因为此类申明仅实用于立刻申明的类——serialVersionUID
字段不可用作继承成员。
其余问题
Q: 如果父类被序列化,默认状况下子类也被序列化,所以咱们也须要为 child 申明 serialVersionUID
吗?
A: 倡议对子类,或者说每一个存在序列化需要的类都进行 serialVersionUID
的指定,并且如上倡议,采纳 private
进行润饰,防止子类对父类的 protected 继承(我还没碰上炸毛的状况,所以也不好讲继承后会在什么状况下呈现什么样的问题)
Q: 如果我不序列化,还须要指定吗?
A:如果不存在序列化需要,也就不存在序列化与反序列化中的比对,原则上不申明 serialVersionUID
也是能够的
欢送关注,一起提高~
发送 SpringBoot 获取 SpringBoot材料礼包