序列化和反序列化
序列化隐秘的吭,你踩过了没?
序列化和反序列化
Java序列化的目的主要有2个:
- 网络传输
- 对象持久化
当2个相对独立的进程,需要进行跨进程服务调用时,就需要把被传输的Java对象编码为字节数组或者ByteBuffer对象。
接收方只需要把这些字节数组或者Bytebuf对象重新解码成内存对象即可实现通信、调用的作用。
那么在我们使用序列化的时候有哪些需要注意的,避免的坑呢?
成员变量不能以is开头
阿里的《Java开发手册》明文规定了:成员变量禁止使用类似 isXxxx 的命名方式,也不要有isXxx命名的方法
大概的意思就是:不要加is
前缀,因为部分框架序列化的时候,会以为对应的字段名是isXxxx
后面的Xxxx
- 比如:
isSucceed
序列化成Succeed
,前端读取isSucceed的时候就会发现没有这个字段,然后出错了。
这里面的序列化框架其实就是fastjson
,我们可以直接去看他的源码
fastjson源码分析:computeGetters
去找get前缀的方法,然后进行字符串切割找到get后面的
去找is前缀的方法,然后进行字符串切割
- 这里还进行了驼峰命名的判断:ixXxx,第三个字符是否是大写等判断
所以isSucceed
字段会被fastjson框架认为Succeed
字段。
默认值
成员变量的默认值同样会带来坑
同样是阿里的《Java开发手册》里面也是规定了:POJO类、RPC方法必须使用包装类型。
关于包装类型和基本类型的区别,如果还有不清楚的,赶紧去看,这是最基础的面试知识点..
POJO类必须使用包装类型
尽量让错误暴露在编译期,不要拖到运行期
基本类型具有初始值,比如:
Int
:0float
:0.0fboolean
:false
一个统计点赞的接口里面的返回值包含一个表示点赞数变化的字段,当发生错误的时候,这个字段没有进行赋初始值,就会出现以下情况:
- 基本类型:读默认值,
0
,表达的意思就是没有点赞数变化,程序上并不知道是服务器那边出了错。 - 包装类型:读到了个
null
,程序上是知道服务器那边出错了,可以进行对应的显示,比如显示 - ,表示读取不到等操作。
总的来说就是:如果字段设置为基础类型并且基础类型的默认值具有业务意义,那么就会出错,并且无法感知错误
RPC方法的返回值和参数必须使用包装类型
RPC调用常常具有超时导致调用失败的情况
如果用包装类型,那么在接收方,就能感知到,这次RPC调用是成功,还是失败。
包装数据类型的null值具有表示额外的信息功能。
彦祖来都来了,点个赞👍再走吧,这对我来说真的非常重要
来源:juejin.cn/post/7205478140914843709