什么是Java序列化
- 将JVM中的对象转化字节流,或者将该字节流存储到硬盘上(持久化存储),用于以后恢复回对象(反序列化),或者将该字节流通过网络传输,之后在网络的其他节点恢复成对象(反序列化)。
Java序列化的作用
- 将JVM中的对象转化为字节流,方便存储到硬盘上或者在网络上传输。
如何实现序列化和反序列化
实现序列化:
- 实现Serializable接口(或者父类实现)
- 只需要标注该接口就行,不需要实现该接口的方法
- 如果不在类中实现writeObject和readObject方法,那么将采用默认的序列化机制,否则将调用这两个方法实现序列化和反序列化。如果你实现了这两个方法的同时,又想利用Java的默认序列化,那么就在两个方法中分别调用defaultWriteObject和defaultReadObject方法,这种方式可用于对象加密。
- 可以用transient修饰不必序列化的属性。
- 实现Externalizable接口,并且实现该接口的writeExternal和readExternal方法,自己对序列化的内容进行控制。(或者父类实现)
- 实现Serializable接口(或者父类实现)
反序列化:
- 对于实现Serializable接口的类,并不要求该类具有一个无参的构造方法, 因为在反序列化的过程中实际上是去其继承树上找到一个没有实现Serializable接口的父类(最终会找到Object), 然后构造该类的对象, 再逐层往下的去设置各个可以反序列化的属性(也就是没有被transient修饰的非静态属性).
- 对于实现Externalizable接口的类,需要其拥有无参构造器,因为对该类对象进行反序列化先走构造方法得到控对象,然后调用readExternal方法读取序列化文件中的内容给对应的属性赋值。
- 注意事项:
- 对象的类名、属性会被序列化,方法不会被序列化。
- transient修饰的属性和static属性不会被序列化。
- 要保证需要被序列化的属性也是可序列化的。
- 反序列化时,需要按照序列化顺序读取相应对象。
- 进行反序列话的JVM需要拥有序列化对象所属的类的class文件,且文件中的serializableID的值要相同,最好显示声明serializableID的值。
常见的序列化协议有哪些
按照http://blog.csdn.net/a837199685/article/details/50611402整理到此处,具体可点击以上链接查看
- XML
- 定义
- XML(Extensible Markup Language)是一种常用的序列化和反序列化协议, 它历史悠久,从1998年的1.0版本被广泛使用至今。
- 优点
- 人机可读性好
- 可以指定元素或特性的名称
- 缺点
- 序列化数据只包含数据本身和类的结构,不包括类型标识和程序集信息。
- 类必须有一个将由 XmlSerializer 序列化的默认构造函数。
- 只能序列化公共属性和字段,不能序列化方法。
- 文件庞大,文件格式复杂,传输占带宽
- 使用场景
- 当作配置文件存储数据
- 实时数据转换
- 定义
- json(JavaScript Object Notation, JS 对象标记)
- 定义
- JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集, JSON采用与编程语言无关的文本格式,但是也使用了类C语言(包括C, C++, C#, Java, JavaScript, Perl, Python等)的习惯,简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 优点
- 前后兼容性高。
- 数据格式比较简单,易于读写。
- 序列化后数据较小,可扩展性好,兼容性好。
- 与XML相比,其协议比较简单,解析速度比较快。
- 缺点
- 数据的描述性比XML差。
- 不适合性能要求为ms级别的情况。
- 额外空间开销比较大。
- 使用场景
- 跨防火墙访问。
- 可调试性要求高的情况。
- 基于Web browser的Ajax请求。
- 传输数据量较小,实时性要求低(例如秒级别)的服务
- 定义
- Fastjson
- 定义
- Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致。
- 优点
- 接口简单易用。
- 目前Java中最快的json库。
- 缺点
- 过于注重快,而偏离了“标准”及功能性。
- 代码质量不高,文档不全
- 使用场景
- 协议交互。
- 文件输出。
- Android客户端。
- 定义
- Thrift
- 定义
- Thrift并不仅仅是序列化协议,而是一个RPC框架。它可以让你选择客户端与服务端之间传输通信协议的类别,即文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议。
- 优点
- 序列化后的体积小, 速度快。
- 支持多种语言和丰富的数据类型。
- 对于数据字段的增删具有较强的兼容性。
- 支持二进制压缩编码。
- 缺点
- 使用者较少。
- 跨防火墙访问时,不安全。
- 不具有可读性,调试代码时相对困难。
- 不能与其他传输层协议共同使用(例如HTTP)。
- 无法支持向持久层直接读写数据,即不适合做数据持久化序列化协议。
- 使用场景
- 分布式系统的RPC解决方案
- 定义
- Avro
- 定义
- Avro属于Apache Hadoop的一个子项目。 Avro提供两种序列化格式:JSON格式或者Binary格式。Binary格式在空间开销和解析性能方面可以和Protobuf媲美,Avro的产生解决了JSON的冗长和没有IDL的问题。
- 优点
- 支持丰富的数据类型。
- 简单的动态语言结合功能。
- 具有自我描述属性。
- 提高了数据解析速度。
- 快速可压缩的二进制数据形式。
- 可以实现远程过程调用RPC。
- 支持跨编程语言实现。
- 缺点
- 对于习惯于静态类型语言的用户不直观
- 使用场景
- 在Hadoop中做Hive、Pig和MapReduce的持久化数据格式
- 定义
- Protobuf
- 定义
- protocol buffers 由谷歌开源而来,在谷歌内部久经考验。它将数据结构以.proto文件进行描述,通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性。
- 优点
- 序列化后码流小,性能高。
- 结构化数据存储格式(XML JSON等)。
- 通过标识字段的顺序,可以实现协议的前向兼容。
- 结构化的文档更容易管理和维护。
- 缺点
- 需要依赖于工具生成代码。
- 支持的语言相对较少,官方只支持Java 、C++ 、Python。
- 使用场景
- 对性能要求高的RPC调用。
- 具有良好的跨防火墙的访问属性。
- 适合应用层对象的持久化。
- 定义
- 其他
- protostuff 基于protobuf协议,但不需要配置proto文件,直接导包即可。
- Jboss marshaling 可以直接序列化java类, 无须实java.io.Serializable接口。
- Message pack 一个高效的二进制序列化格式。
- Hessian 采用二进制协议的轻量级remoting onhttp工具。
- kryo 基于protobuf协议,只支持java语言,需要注册(Registration),然后序列化(Output),反序列化(Input)。