第五章 java重要知识点(序列化和反序列化)

序列化和反序列化

定义

序列化:把数据结构或对象转换成二进制字节流
反序列化:在序列化过程中所生成的二进制字节流转换成数据结构或对象
Java是面向对象编程语言,序列化的对象是实例化后的类;在C++的半面向对象语言中,结构体定义的是数据结构类型,而类对应的是对象类型。

常见应用场景

1、对象在进行网络传输
2、将对象存储到文件
3、将对象存储到数据库(例如:Redis)
4、将对象存储到内存

常用的序列化协议

Hessian、Kryo、Protobuf、ProtoStuff,这些都是基于二进制的序列化协议。

JDK 自带的序列化方式

只需要实现java.io.Serializable接口即可

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
@ToString
public class RpcRequest implements Serializable {
    private static final long serialVersionUID = 
    1905122041950251207L;
    private String requestId;
    private String interfaceName;
    private String methodName;
    private Object[] parameters;
    private Class<?>[] paramTypes;
    private RpcMessageTypeEnum rpcMessageTypeEnum;
}

serialVersionUID 的作用

中文叫做序列化号。作用是版本控制。
反序列化时,会检查这个UID是否和当前类的UID一致,如果UID不一致会抛出InvalidClassException 异常。如果不手动指定,那么编译器会动态生成默认的UID。
虽然UID被static修饰,但是“序列化”假象:static修饰的是静态变量,位于方法区,本身不会被序列化。static修饰的变量属于类,而不是对象。反序列化后,static变量的值就像是默认赋予了对象一样,是假象。

不进行序列化的字段

用transient修饰
作用:阻止实例中那些用此关键字修饰的变量序列化;当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。
注意:

  1. 只能修饰变量,不能修饰类和方法
  2. 修饰的变量,在反序列化后变量值会被置成类型的默认值

不推荐JDK自带的序列化

1、不支持跨语言调用
如果调用的是其他语言开发的服务就不支持
2、性能差
序列化后的字节数组,体积较大,传输成本高
3、存在安全问题
输入的反序列化的数据可以被用户控制。容易被攻击

Kryo

高性能的序列化工具,变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的字节码体积。
是一种成熟的序列化实现,在开源项目中广泛使用。

Protobuf

出自Google,支持多种语言,同是是跨平台的。使用过程较为繁琐,需要自己定义IDL文件,生成对应的序列化代码。优点:没有序列化漏洞的风险
Protobuf包含序列化格式的定义,各种语言的库,IDL编译器。
用法:定义proto文件,使用IDL编译器编译成我需要的语言

ProtoStuff

基于Protobuf,提供更多的功能和更简易的用法

Hessian

轻量级,自定义描述的二进制RPC协议。跨语言的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值