更新时间:2022-12-13 12:50:02 来源:极悦 浏览798次
Java序列号之Java序列化是什么?极悦小编来告诉大家。
序列化:将对象写入到IO流中
反序列化:从IO流中恢复对象
1.序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上。
2.通过网络传输,以达到以后恢复成原来的对象。
3.序列化机制使得对象可以脱离程序的运行而独立存在。
1.所有可在网络上传输的对象都必须是可序列化的。
2.所有需要保存到磁盘的java对象都必须是可序列化的。
所以基本上每个javaBean类都实现Serializeable接口。
实现Serializable接口或者Externalizable接口之一。
1.序列化步骤:
步骤一:创建一个ObjectOutputStream输出流;
步骤二:调用ObjectOutputStream对象的writeObject输出可序列化对象。
2.反序列化步骤:
步骤一:创建一个ObjectInputStream输入流;
步骤二:调用ObjectInputStream对象的readObject()得到序列化的对象。
3.注意:引用类型类成员
如果一个可序列化的类的成员不是基本类型,也不是String类型,那这个引用类型也必须是可序列化的;否则,会导致此类不能序列化。
4.注意:同一对象序列化多次的机制
【同一对象序列化多次,并不会将此对象序列化多次得到多个对象。】原因如下:(Java序列化算法)
所有保存到磁盘的对象都有一个序列化编码号
当程序试图序列化一个对象时,会先检查此对象是否已经序列化过,只有此对象从未(在此虚拟机)被序列化过,才会将此对象序列化为字节序列输出。
如果此对象已经序列化过,则直接输出编号即可。
5.潜在的问题:
如果序列化一个可变对象(对象内的内容可更改)后,更改了对象内容,再次序列化,并不会再次将此对象转换为字节序列,而只是保存序列化编号。
所以,比较反序列化后,两个对象更改的内容属性,任然是相同的。
6.自定义序列化:
(1)使用transient关键字选择不需要序列化的字段。对于引用类型,值是null;基本类型,值是0;boolean类型,值是false。
(2)通过重写writeObject与readObject方法,可以自己选择哪些属性需要序列化, 哪些属性不需要。
(3)如果writeObject使用某种规则序列化,则相应的readObject需要相反的规则反序列化,以便能正确反序列化出对象。这里展示对名字进行反转加密。
(4)当序列化流不完整时,readObjectNoData()方法可以用来正确地初始化反序列化的对象。
(5)彻底的自定义序列化:
1)writeReplace:在序列化时,会先调用此方法,再调用writeObject方法。此方法可将任意对象代替目标序列化对象
2)readResolve:反序列化时替换反序列化出的对象,反序列化出来的对象被立即丢弃。此方法在readeObject后调用。
3)readResolve常用来反序列单例类,保证单例类的唯一性。
1.通过实现Externalizable接口,必须实现writeExternal、readExternal方法。
注意1:Externalizable接口不同于Serializable接口,实现此接口必须实现接口中的两个方法实现自定义序列化,这是强制性的;
注意2:特别之处是必须提供pulic的无参构造器,因为在反序列化的时候需要反射创建对象。
Serializable:系统自动存储必要的信息、易于实现,只需要实现该接口、性能略差
Externalizable:程序员决定存储哪些信息、必须实现接口内的两个方法、性能略好
1.作用:
反序列化必须拥有class文件,但随着项目的升级,class文件也会升级为保证升级前后的兼容性:
java序列化提供了一个serialVersionUID 的序列化版本号,只有版本号相同,即使更改了序列化属性,对象也可以正确被反序列化回来。
2.不指定版本号的隐患:
序列化版本号如果不指定,JVM会根据类信息自己计算一个版本号,这样随着class的升级,就无法正确反序列化;
不指定版本号另一个明显隐患是,不利于jvm间的移植,可能class文件没有更改,但不同jvm可能计算的规则不一样,这样也会导致无法反序列化。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习