39 序列化和反序列化

2020-04-13  本文已影响0人  ca8519be679b
1

一张解释序列化和反序列化,如上,我们创建Person类实例,想把它存储到文件中,可以使用流方式写入,叫做序列化,因为对象不仅包括字符,所以要用字节流写,这里使用ObjectOutputStream,即按对象输出序列化,有方法,writeObject(Object obj)写入到某文件中,因为是字节流,我们看不懂,流存储就需要流读取,使用ObjectInputStream反序列化输入流,读取来的对象我们不知道是什么类,因为类型不一定固定,所以用Object对象接收

ObjectOutputStream序列化输出流

既然说完了,那就来学习怎么使用

2

其继承自字节输出流,将对象以流的方式写入文件

3

构造方法2个,视频推荐后者,传入字节输出流参数

4

其特有成员方法是将对象写入到序列号流中,

5

然后我们就信誓旦旦的去写代码了,就发现了错误,提示未序列化异常,果然还是不能简单实用Person对象来直接使用,而序列化接口是java.io.Serializable中,我们需要implements它,所有需要序列化或者反序列化的类都必须实现它,实现后,该类就添加了标记,我们进行序列化或者反序列化就可以正常进行,否则就会报错(就像肉盖有检疫章一样)

6

修改后,运行正常

ObjectInputStream反序列化输入流

7

将文件中保存的对象以流方式读出来,继承自字节输入流

8

其自身方法readObject()获取文件对象

8

代码如上,注意的是,readObject需要抛出未找到类异常,为了使用对象需要强转类型

瞬态关键字transient

我们知道静态关键字static,修饰成员变量时,优先于对象加载到内存中,所以被static修饰的成员变量时不能被序列化的

9

我们给Person的age修改为static,则其序列化后,再用另一个文件反序列化,运行发现年龄不是13而是默认值,(但是当我用一个文件调用2个函数是可以得到序列化的值的)

10

同样,将属性设置为transient也是不可序列化的

InvalidClassException异常

我们之前反序列化需要注意IO异常,和类未找到异常,还有新的异常,如果我们按Person类进行序列化并存储到文件,但是反序列化前,将Person类修改,例如某个属性设置为private->public

11

反序列化后就会报错,提示序列化编号不匹配

12

我们因为类实现了Serializable接口,所以编译后会给你其添加序列号,我们序列化后文件就会存储序列化号,当我们反序列化,就会比对文件序列化号和类序列化是否一致,如果我们修改了,那就会编译导致类序列化号不一致报错,我们如果频繁修改类,那序列化就会很麻烦,可序列化类可以通过声明名为"serialVersionUID"的字段(该字段必须是静态 (static)、最终 (final) 的long型字段)显式声明其自己的 serialVersionUID:

static final long serialVersionUID = 42L; 给Person类添加这个序列化号字段,则这个序列化号就是指定不变的

练习DEMO

序列化集合,集合可以序列化多个对象,我们如此存储

13

序列化部分如上

14

反序列化读取如上

上一篇下一篇

猜你喜欢

热点阅读