带着问题来学习.
1.序列化是什么,有什么作用?
2.序列化有什么方式?
3.java的序列化以及应用场景是什么?
4.serialVersionUID 的作用是什么?
1.序列化是什么,有什么作用?
先看看美团一篇文章中的描述,原文点这里.
互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分。通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如:TCP/IP协议是一个四层协议,而OSI模型却是七层协议模型。在OSI七层协议模型中展现层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象--这两个功能就是序列化和反序列化。一般而言,TCP/IP协议的应用层对应与OSI七层协议模型的应用层,展示层和会话层,所以序列化协议属于TCP/IP协议应用层的一部分。本文对序列化协议的讲解主要基于OSI七层协议模型。
- 序列化: 将数据结构或对象转换成二进制串的过程
- 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程
简单的理解,A,B双方需要传递一些数据,只能以二进制方式传输,然后就A就通过序列化把对象变成二进制串,B接收到二进制串再反序列化成对象.
序列化,反序列化可以说是这些转换的规则,
传输数据就是序列化的作用.大部分讲java序列化的应用,都会讲把对象存到硬盘之类的,这也是传输数据的一种.
2.序列化有什么方式?
序列化的方式,其实就是序列化的协议.有很多种,xml,json,Thrift,Protobuf,Spearal等等
但是最常见的是xml和json. 这2中形式都有很好的可读性.
xml由于比较笨重(空间开销大),貌似现在互联网用的较少,传统行业还是多点(web service).
至于各种方式的优劣点,可以参考这里 (老外测试的,多种序列化协议各方面对比).
3.java的序列化以及应用场景是什么?
java的序列化是通过实现Serializable接口来实现的.当一个类实现这个接口后,就会被标记为可序列化.
实现Serializable后,序列化是用默认的方式实现的,如果想自己控制(例如过滤字段及加密文本等)可以实现Externalizable接口,自己覆盖writeExternal和readExternal方法.
如果是简单的某个字段不需要序列化,例如密码,则可以指定字段为transient.
还有一种方法控制序列化,就是在实现Serializable的类里面,添加writeObject()和readObject()方法.如下:
private void writeObject(ObjectOutputStream stream) throws ClassNotFoundException, IOException{}
private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException{}
就算是private的,在序列化的时候也会被调用,神奇.(可参看think in java 18.12.2);
下面再说说序列化的应用场景:
1).一些配置信息持久化到文件
2).远程方法调用.
3).保存对象到redis(之类)中.
可能还有别的场景吧. 我就用到了保存到redis这个,jeids的api中,保存参数是byte[],把对象转换成byte[],就需要用到序列化.
4.serialVersionUID 的作用是什么?
在eclipse中,当一个类实现Serializable接口后,都会有个警告,大意就是需要一个serialVersionUID.
从字面意思就不难看出,这个字段是序列化的版本.
序列化的时候,会把这个字段一起处理, 当反序列化的时候,会拿当前类的这个字段去和反序列化出来的这个字段做对比.
如果一致,则正常处理.
如果不一致,则抛出异常InvalidClassException.
如果不写这个字段,则序列化时会自动计算一个值来作为版本号,当类的属性变更后,新计算出来的版本值就会和以前不同,这时候反序列化以前的就会报错.