JDK 序列化 serialVersionUID应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Daybreak1209/article/details/80668783
通常,RPC调用有多种序列化方式,本文简单介绍一下JDK自带的序列化接口Serializable使用事项。

一、serialVersionUID

一般实现Serializable接口的序列化对象会要求声明一个long型的serialVersionUID(非强制,不写会有默认值),该变量有何用?

1、序列化操作时,系统会把当前类声明的serialVersionUID写入到序列化文件中,用于反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

2、当实现当前类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果类信息进行修改,会导致反序列化时serialVersionUID与原先值无法match,反序列化失败。

【考虑一下动态生成versionId情况,除非是任意一端已经序列化后,类修改,另一端反序列化match失败。rpc序列化场景是这样的:客户端传来类进行序列化--传输到服务端--服务端经过反序列化后,进行结果组装在序列化返回给客户端,客户端反序列化解析结果。感觉这种场景,哪个点也不会接收到类信息修改导致versionId改变吧。??】

故为在类修改前后序列化兼容,就需要显式地定义一个名为serialVersionUID,类型为long的变量,类发生改动也无需修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

3、serialVersionUID有两种显示的生成方式:        
1)默认1L,比如:private static final long serialVersionUID = 1L; (若所有需序列化实体均采用默认值,无实际意义)
2)根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:      
private static final  long   serialVersionUID = xxxxL;

4、idea配置默认声明serialVersionUID,红框打钩,应用即可。

二、Sonar Case

在项目跑sonar时出现以下case提示


图1表示Address类在没实现序列化时,被一个序列化类所依赖,会导致Person类序列化失败。即序列化类中所依赖的所有对象都应该是实现了Serializable接口的。如果依赖类是一个泛型T,则直接写成

public class Result<T extends Serializable> implements Serializable {}即可

三、Transient

如何让序列化类忽略某些不需要进行序列化的属性--->Transient ,
1 、serialization会忽略掉
transient java 关键字,用来修饰一个序列化对象中不需要进行序列化的部分属性 。当一个对象被序列化时 ,transient型变量的值不包括在序列化 中,然而非transient型的变量是被包括进去的。

private transient int code;

2 、ORM框架中@Transient 修饰实体某属性,表示该表中没有这个字段,不做持久化映射。

猜你喜欢

转载自blog.csdn.net/Daybreak1209/article/details/80668783