参考文档:
序列化与反序列化:http://kb.cnblogs.com/page/515982/
jdk中的序列化api:http://blog.csdn.net/abc6368765/article/details/51365838
jdk中如何序列化:http://www.cnblogs.com/redcreen/articles/1955307.html
什么是序列化&为什么要序列化
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象
主流序列化框架
按照序列化后的数据格式,主流的序列化框架主要可以分为四大类:
JSON类
非常流行的Jackson
Google的Gson。 Gson是目前功能最全的Json解析神器,无依赖,直接跑在jdk上。性能稍逊于fastjson
类JSON的MessagePack
阿里的FastJSON。性能最好。无依赖,不需要例外额外的jar,能够直接跑在JDK上
二进制类
老牌劲旅Hessian(以前很喜欢用的)
功能全面而强大的FST
后起之秀Kryo
XML类
StAX(Streaming API for XML)
Thoughwork的XStream
RPC类(都要安装、编译)
Protobuf
Thrift
Apache Avro
判断一个编码框架的优劣主要从以下几个方面
- 是否支持跨语言,支持语种是否丰富
- 编码后的码流存储空间
- 编解码的性能
- 类库是否小巧,API使用是否方便
java序列化的缺点
- 无法跨语言。这应该是java序列化最致命的问题了。由于java序列化是java内部私有的协议,其他语言不支持,导致别的语言无法反序列化,这严重阻碍了它的应用
- 序列后的码流太大。java序列化的大小是二进制编码的5倍多
- 序列化性能太低。java序列化的性能只有二进制编码的6.17倍
jdk类库中的序列化api
序列化的实现
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式
ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中
ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回
serialVersionUID的作用
s?e?r?i?a?l?V?e?r?s?i?o?n?U?I?D?:? ?字?面?意?思?上?是?序?列?化?的?版?本?号?,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量
serialVersionUID有两种生成方式:
serialVersionUID是1L
private static final long serialVersionUID = 1L;
在可兼容的前提下,可以保留旧版本号,如果不兼容,或者想让它不兼容,就手工递增版本号。
serialVersionUID是依据类名,接口名,方法和属性等来生成的hash值:
private static final long serialVersionUID = 4603642343377807741L;
是根据类的结构产生的hash值。增减一个属性、方法等,都可能导致这个值产生变化。我想这种方式适用于这样的场景:开发者认为每次修改类后就需要生成新的版本号,不想向下兼容,操作就是删除原有serialVesionUid声明语句,再自动生成一下
举例:
User类序列到到kafka中,如果不指定serialVersionUID,该user类新增加了一个age属性,在反序列化的时候,则会抛出异常,拒绝载入。是因为改动user类以后,生成了一个新的serialVersionUID,与存储在kafka中的已经序列化的serialVersionUID版本不一致。所以反序列化发生冲突
静态变量序列化
序列化保存的是对象的状态,静态变量属于类的状态,因此序列化并不保存静态变量
父类的序列化
父类实现接口后,所有派生类的属性都会被序列化。子类实现接口的话,父类的属性值丢失
Transient关键字
Transient关键字的作用是控制变量的序列话,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
原文地址:https://www.cnblogs.com/amei0/p/8480260.html