标签:
1.什么是Java序列化与反序列化?
- 序列化:将java对象转换为字节序列的过程叫做序列化
- 反序列化:将字节对象转换为java对象的过程叫做反序列化
2.为什么需要Java序列化与反序列化?
2.1. 存储
在java系统运行过程中,java对象只存在于堆栈中,但是一旦系统停止运行了,或者某次交互回话结束后,这些java对象也不存在了。
想要再次获得java对象,则需要从一些存储设备中读取数据,并且还原为原先的java对象,系统才可以再次正常运行。
这里存储设备,可以是文件,缓存(比如EhCache,MemCache,redis等等),甚至是数据库中,都可以,保存这些对象的字节流,等待java对象再次复活!
2.2. 传输&交换
分布式系统中,系统之间交互,比如通过java原生的RMI远程调用,返回的字节流反序列化为java对象,才能在jvm里运行。
或者当下常用的分布式架构,http+json返回的json数据,也是需要反序列化为java对象,只是用的方法和jdk原生不同罢了,
以及新的分布式架构,thrift,dubbo等,返回的数据是字节流的形式,也是需要反序列化。
3.怎么Java序列化与反序列化?
3.1 Java JDK自带的序列化工具有:
- java.io.ObjectOutputStream:代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
- java.io.ObjectInputStream:代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以,采用默认的序列化方式 。
3.2 对象序列化一般包括如下步骤:
- 1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
- 2) 通过对象输出流的writeObject()方法写对象。
3.3 对象反序列化的步骤如下:
- 1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
- 2) 通过对象输入流的readObject()方法读取对象
特殊说明下:实现Serializable接口的java对象,有一个serialVersionUID,serialVersionUID: 字面意思上是序列化的版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。
同一个java对象,只要序列化ID相同,属性相同,那么反序列化会正常的执行
同一个java对象,如果序列化ID不同,属性相同,反序列化都不会成功
因为默认的JDK序列化与反序列化方法要求必须实现Serializable接口,并且序列化ID相同,这时jvm才认可字节流是可以反序列化的,
和json的反序列化则一样(不再详细说明)
4. 有没有造好的轮子?
java序列化的框架目前也不少,具体实现没来得及一一研究,有基于json反序列化的(GSON,Jackson),有基于字节流实现的(protobuf),以及基于xml等等
5. 总结
序列化的规则就像一种协议,一种约定一样,序列化的意义在于信息的交换和存储。
Java序列化与反序列化
标签:
原文地址:http://my.oschina.net/ilaoda/blog/504631