Java序列化

序列化和反序列化,这个名词的定义,就是为了网络传输,因为网络传输是二进制,那就需要定义和标准。

定义

序列化:将对象写入到IO流中

反序列化:从IO流中恢复对象

意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。

使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。

在Java中,有几种序列化的方式,分别是:Java自带的序列化、Hessian、Protobuf、Thrift,这里一一展开。

Java自带序列化

Serializable接口是一个标记接口,不用实现任何方法。一旦实现了此接口,该类的对象就是可序列化的。

序列化步骤:

步骤一:创建一个ObjectOutputStream输出流;

步骤二:调用ObjectOutputStream对象的writeObject输出可序列化对象。

反序列化步骤:

步骤一:创建一个ObjectInputStream输入流;

步骤二:调用ObjectInputStream对象的readObject()得到序列化的对象。

同一对象序列化多次,不会将这个对象序列化多次

transient关键字的特点:使用transient修饰的属性,java序列化时,会忽略掉此字段,所以反序列化出的对象,被transient修饰的属性是默认值。对于引用类型,值是null;基本类型,值是0;boolean类型,值是false。

Externalizable接口:不同于Serializable接口,实现此接口必须实现接口中的两个方法实现自定义序列化,这是强制性的;特别之处是必须提供pulic的无参构造器,因为在反序列化的时候需要反射创建对象。

JAVA序列化与反序列化三种格式存取(默认格式、XML格式、JSON格式),后面2者的关键类是:XStream、SerializeJSON

Protobuf

Protobuf 是谷歌提出的一种序列化协议,Protobuf 是一种接口定义语言,它与语言和平台无关。它是一种序列化结构化数据并通过网络传输的方式,使用 Protobuf 传输二进制文件,与 JSON 的字符串格式相比,它提高了传输速度。

Protobuf 是一种接口定义语言,也是一种语言,有自己的关键字以及规则,需要创建一个后缀为 .proto 的文件。

Protobuf提供的序列化与反序列化的高效性。相对于传统的java提供的序列化来说,Protobuf的效率提高了很多倍。

但是也有不足的地方,就是proto在对象序列化的时候抛弃了很多数据。比如:类的相关属性。只保留了数据部分。提高了传输的效率,减少带宽的占用。

Thrift

Thrift 也是一种序列化协议,具体的使用方式跟 Protobuf 类似,是 Facebook 提出来的一种协议。

Thrift 的使用方式跟 Protobuf 类似,也是有一个 .thrift 后缀的文件,然后通过命令生成各种语言的代码。

总结

每个协议有每个协议的特点,具体选择哪种协议我们要根据实际的场景来选择。

前后端对接,则 JSON 最合适,网页的交互要求不需要太高,秒级别是可以接受的,更加关注可读性。

微服务之间的数据传输,选择 Protobuf 或者 Thrift 这种更高效的协议来进行传输,因为这种场景对于协议序列化的体积和速度都有很高的要求。

唠嗑广场

看看运营商们,是怎么宣传网络诈骗的~

中国移动:谨防电信诈骗

中国电信:小心移动支付陷阱

中国联通:注意移动支付中的电信诈骗