序列化Serializable


原博文,点击这里
父子之间序列化之间的关系,点击这里

1.序列化的作用:

如果你的对象需要网络传输或者持久化(对象直接转换为字节的形式传输),那么就需要实现Serializable接
口。为了防止反序列失败,该对象需提供一个默认的serialVersionUID(该值在反序列化的时候会进行校验,
如果校验失败会抛异常-InvalidClassException)。

提问:现在需要将一个对象返回给前端,那么该对象是否需要实现 Serializable接口,并提供一个默认的serialVersionUID,如果不实现会有什么影响?

我们现在想一个问题,现在一般前后端进行数据交互一般都是json格式 (json格式数据其实就是String) 的数据,那么是谁在什么时候将我们的对象转换成json格式的?只要想明白这个问题,也就解决了我们提出的疑问。

这里我先用SpringMVC框架做一番解释,我们使用SpringMVC框架的时候如果要返回一个json串给前端只需要将对象返回并且在方法上加上@ResponseBody注解,类似以下操作:
在这里插入图片描述
SpirngMVC又是在什么时候由哪个类处理@ResponseBody这个注解的呢?

SpringMVC 中处理@ResponseBody主要是通过类:RequestResponseBodyMethodProcessor#handleReturnValue处理返回值,解析成json又涉及到的HttpMessageConverter的配置,其实正常情况下SpringMVC是自动帮我们配置以下转换器:

① ByteArrayHttpMessageConverter

② StringHttpMessageConverter

③ ResourceHttpMessageConverter

④ SourceHttpMessageConverter

⑤ AllEncompassingFormHttpMessageConverter

是否引入jackson包配置MappingJackson2HttpMessageConverter。

具体详见WebMvcConfigurationSupport#addDefaultHttpMessageConverters。一般执行解析操作的是MappingJackson2HttpMessageConverter这个类,其实这个类不是干实事的,具体操作还得交给ObjectMapper这个类取实现。而ObjectMapper就是jackson包中的一个类。

jackson是怎么将对象转换成json的?

jackson将对象解析成json的入口是ObjectMapper#writeValueAsString,其内部实现大概是先初始化一个4000容量的WriterBasedJsonGenerator#_outputBuffer char数组,然后将对象中的字段一一往char数组中放入,最后将char数组转换成String。具体详见ObjectMapper#writeValueAsString,因此对象转换成json与Serializable无关。

验证:

如果一个对象进行序列化跟实现Serializable有关系的话,那么序列化的过程中一定就会调用该对象下的writeObject(java.io.ObjectOutputStream s) ,因此只需启动程序调用接口,在方法writeObject上打断点,看是否可以拦截住。这里使用HashSet做实验。会发现断点没有停住。说明使用SpringMVC框架返回给前端的对象无需实现Serializable接口,其大致图如下:
在这里插入图片描述

因此真正与网络传输打交道的是SpringMVC转换后的json字符串,实体对象与网络并没用直接的接触,所以这里的实体对象无需实现Serializable接口。

总结:

一般来说如果你的对象需要网络传输或者持久化 (对象直接转换为字节的形式传输),那么就需要实现Serializable接口。比如远程方法调RPC (Remote Procedure Call) 则接口参数就一定要实现Serializable接口;如果只是转换为json字符串的形式与网络打交道,那么就不需要实现Serializable接口。

自动生成serialVersionUID

实体对象实现了java.io.Serializable接口后,一般都会提供一个serialVersionUID以做版本区分。在idea里,可以通过设置来快速生成serialVersionUID。

设置方法

1、打开Preferences–>Editor–>Inspections,然后在右侧输入UID进行搜索(搜索方式比较快,也可以在java–>Serialization issues里找)。然后勾选Serializable class without 'serialVersionUID’后面的复选框。右侧Severity默认Warning即可。如下图:
在这里插入图片描述

2、测试,新建一个实体Student,实现java.io.Serializable接口,然后将光标放到类名Student上,按option+return(window按alt+enter,快捷键可能不一样,根据自己的设置来)打开提示框,选择Add ‘serialVersionUID’ field确定即可,如下图:
在这里插入图片描述

生成的serialVersionUID如下:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值