java对象的序列化和反序列化
2016-03-29 14:56
369 查看
文章参考 /article/4676439.html
一、序列化和反序列化的概念
把对象转换为字节的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1)把对象的字节序列永久的保存到硬盘上,通常放置到一个文件中;
2)在网络上传输对象的字节序列。
例如:在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
二、JDK类库中的序列化API
java.io.ObjectOutputStream代表对象的输出流,他的writeObject(Object obj)方法可对参数制定的obj对轩昂进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象的输入流,他的readObject(Object obj)方法从一个源输入流中读取字节序列,再把他们反序列为一个对象,并将其返回。
java中只有实现了Serializable和Externalizable接口的对象才能被序列化。Externalizable接口集成Serizalizable接口。区别如下:
Serializable接口:
1)系统自带的类序列化方法,主要包括writeObject(Object obj)方法来序列化和readObject(Object obj)方法来进行反序列化。类的序列化包含对象的类型和数据域。
2)如果类中的那个数据域不应该被序列化,那么应该将他标记成transient类型。
Externalizable接口:
1)这个接口是java提供的用户自己进行对象的序列化方法,用户必须实现readExternal()和whiteExternal()方法。
2)实现这个接口后,对象序列化的全部职责有自己负责,包括父类的数据和自己的数据。一般情况下主要是用户自定义一种序列化方式,只有数据域,没有对象的类型等,方便处理。
三、类的初始化过程(serializable接口原理)
注意:
每个对象都被赋予一个序列号。
相同对象的重复出现将被存储为对这个对象序列号的引用。
1)当序列化一个对象的时候,首先看这个对象的类是否已经序列化到输出流中。如果没有,则首先将这个类序列化后输出,然后关于类会形成一个指纹(根据类,超类等信息生成,跟serialVersionUID有关,后面会讲到),以后遇到这个类的对象的时候,直接将这个指纹号写到对象中,也就是说类只会被序列化一遍。
2)接着,开始序列化队对象。对象序列化的时候也会有个序列号,如果这个对象被多次引用,则下一次出现的时候直接将这个序列号写到相应位置即可。
四、类的版本管理(serialVersionUID应用)
如果一个类序列化后保存到文件中后,这个类改变了,那么相应类的指纹也改变了。当进行对象的反序列化时候由于类指纹不相同,所以不能进行加载,这就是版本冲突。
解决:可以在所有实现了Serializable接口的类中增加serialVersionUID来进行版本管理,因为在生成指纹的时候如果有这个数据,则直接使用serialVersionUID。那么当该改变类的时候,不改变这个数据,他们的指纹应该是一样的,就可以进行版本兼容了。(不过如果改变前和改变后数据域不一样的化,就会出现问题)
一、序列化和反序列化的概念
把对象转换为字节的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1)把对象的字节序列永久的保存到硬盘上,通常放置到一个文件中;
2)在网络上传输对象的字节序列。
例如:在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
二、JDK类库中的序列化API
java.io.ObjectOutputStream代表对象的输出流,他的writeObject(Object obj)方法可对参数制定的obj对轩昂进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象的输入流,他的readObject(Object obj)方法从一个源输入流中读取字节序列,再把他们反序列为一个对象,并将其返回。
java中只有实现了Serializable和Externalizable接口的对象才能被序列化。Externalizable接口集成Serizalizable接口。区别如下:
Serializable接口:
1)系统自带的类序列化方法,主要包括writeObject(Object obj)方法来序列化和readObject(Object obj)方法来进行反序列化。类的序列化包含对象的类型和数据域。
2)如果类中的那个数据域不应该被序列化,那么应该将他标记成transient类型。
Externalizable接口:
1)这个接口是java提供的用户自己进行对象的序列化方法,用户必须实现readExternal()和whiteExternal()方法。
2)实现这个接口后,对象序列化的全部职责有自己负责,包括父类的数据和自己的数据。一般情况下主要是用户自定义一种序列化方式,只有数据域,没有对象的类型等,方便处理。
三、类的初始化过程(serializable接口原理)
注意:
每个对象都被赋予一个序列号。
相同对象的重复出现将被存储为对这个对象序列号的引用。
1)当序列化一个对象的时候,首先看这个对象的类是否已经序列化到输出流中。如果没有,则首先将这个类序列化后输出,然后关于类会形成一个指纹(根据类,超类等信息生成,跟serialVersionUID有关,后面会讲到),以后遇到这个类的对象的时候,直接将这个指纹号写到对象中,也就是说类只会被序列化一遍。
2)接着,开始序列化队对象。对象序列化的时候也会有个序列号,如果这个对象被多次引用,则下一次出现的时候直接将这个序列号写到相应位置即可。
四、类的版本管理(serialVersionUID应用)
如果一个类序列化后保存到文件中后,这个类改变了,那么相应类的指纹也改变了。当进行对象的反序列化时候由于类指纹不相同,所以不能进行加载,这就是版本冲突。
解决:可以在所有实现了Serializable接口的类中增加serialVersionUID来进行版本管理,因为在生成指纹的时候如果有这个数据,则直接使用serialVersionUID。那么当该改变类的时候,不改变这个数据,他们的指纹应该是一样的,就可以进行版本兼容了。(不过如果改变前和改变后数据域不一样的化,就会出现问题)
相关文章推荐
- spring mvc返回类型总结(主要是对返回路径的总结)
- Java框架基础——反射(reflect)
- java中的常用集合和线程安全
- Java中避免NullPointerException的一些方法
- JAVA异常机制
- Struts---- <s:bean>标签
- JeeSite是基于多个优秀的开源项目,高度整合封装而成的高效,高性能,强安全性的 开源 Java EE快速开发平台
- java进制转换成字符串
- java字符串的各种编码转换
- java连接SQL Server 2012
- java中private,protected,public的default的区别
- java 去除末尾的零 如果小数点可以去除同时去除小数点
- Java基础
- Could not commit Hibernate 异常问题,spring 事物 提交前session关闭问题
- Eclipse vs. IDEA快捷键对比大全
- Eclipse中应用Sublime主题界面
- java后台接口调用
- Eclipse出现Failed to create the part's controls
- Eclipse4.4集成Groovy插件
- JAVA学习初步:百鸡百钱问题算法解及暴力解