从零开始的Java学习记录(39)——字节对象流ObjectInput(Output)Stream
坚持锻炼_千山
2019年03月06日 21:51
收录于文集
共41篇

内容概览


1. 对象流与Serializable接口

对象流即ObjectInputStream与ObjectOutputStream,顾名思义是专门用来输出与输入对象的流,对象流有个限定条件,即被对象流读写的实体类必须实现或间接实现Serializable接口。

Serializable接口即可序列化接口,此接口中并没有方法,而是根据继承该接口的实体类属性生成一串long类型的数字。这个数字的意义在于告知系统读写数据的规则。

序列化:按照某种规则输出至文件。

反序列化:按照序列化的规则读取至内存。

新建一个类实现序列化接口

 


2. 演示对象流

先封装一个writeList的方法:

封装输出流

 

再封装一个readList的方法:

封装输入流

 

输出和读取一个集合:

演示

 

User.txt的文件是这样的乱码,是看不懂的233:

给虚拟机看的乱码

可能会有人困惑,实现Serializable的意义是什么,在以上操作中并没有体现出来,因为我们刚刚是按正常操作来的,试想如果在name属性之前新增一个id属性,那么原先的规则读取会如何读取,张三李四等都变成id吗,这时候我们就改变了实体类的结构,Java无法按照修改后的User类提取user.txt中的属性:

新增一个id属性

 

测试:

报异常

 虽然看上去serialVersionUID没变,实际上已经变了,变成了-4348471268914311791,seriaVersionUID不匹配就会抛出异常。

 

对象流的意义在于能够根据写入的规则还原对象,而不是读取仅仅一串User{name=”张三”,age=20}的字符串。

 


3. 静态与被triansient修饰的不会被序列化

由于静态是从属于类的,是被每个角色共享的,所以对其序列化没有意义。

但如果是非静态,又不想被序列化,则可用triansient修饰该属性:

被static或triansient修饰的属性不会被序列化

 

测试:

测试

 

就算把id和国籍删掉,也不会对序列化有影响,只是方法需要修改:

删除id与国籍属性

演示:

测试