序列化
序列化原理
java序列化就是把java对象保存为二进制字节码的, 反序列化就是把二进制码重新转化成java对象的过程。以字节流的形式。 例如:tomcat关闭,session中的对象存储在硬盘上,及tomcat重启时,从session中读取内容。
两种情况下我们使用序列化
一:
一般情况下java对象的生命周期比java虚拟机要断,实际使用中我们希望在jvm停止运行之后能够持久化指定的对象,这时候就需要把对象进行序列化保存。
二:
java队形通过网络传输时,应为数据只能够以二进制形式在网络中传输,所以需要把对象通过网络发送出去前需要先序列化成二进制数据,在接收端读到二进制数据之后反序列化成java对象。
两种实现序列化的方式
一:实现Serializable接口,接口内没有逻辑,只是相当于一个标识,代表该对象可以被序列化。 二:实现Externalizable 接口在writeExternal()方法里定义了哪些属性可以序列化,哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自动调用readExternal()方法,根据序列顺序挨个读取进行反序列,并自动封装成对象返回,然后在测试类接收,就完成了反序列。
http://www.importnew.com/24490.html 序列化底层介绍
注意
1.序列化是的transient 告知我们该属性不可被序列化 eg: private transient String password;
2.也是最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象是先被序列化的对象,不要先接收对象B,那样会报错.尤其在使用上面的Externalizable的时候一定要注意读取的先后顺序。
serialVersionUID
Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
两种显示的生成方式:
一个是默认的1L,比如:private static final long serialVersionUID = 1L; 一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: private static final long serialVersionUID = xxxxL; 当你一个类实现了Serializable接口,如果没有显示的定义serialVersionUID,Eclipse会提供这个 提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会 自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也 可以把它关掉的,设置如下: Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems 将Serializable class without serialVersionUID的warning改成ignore即可。当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class(它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的)自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释,等等),就算再编译多次,serialVersionUID也不会变化的.