当前课程知识点:Java程序设计 > 第五章 输入输出 > 5.3.7-对象序列化 > 对象序列化
大家好
欢迎回来继续学习
Java语言程序设计
在这一节我们
来学习对象的序列化
什么是对象的序列化呢
我们想一想我们
在程序内存中的对象
它能存活多长时间呢
它最长的寿命也就是
到时候程序运行结束吧
程序一结束了
程序所占有的空间就都释放了
内存里面这些对象也就不存在了
如果这些对象中
有些信息是需要我们永久保留的
那么这个时候
就要进行对象的序列化
也就是说把这个对象
按照整体写到文件中
再整体读出来
我们要实现对象的读写
需要用到这样两个类
通过ObjectOutputStream
可以讲对象整体写入文件中
通过ObjectInputStream
可以把以前曾经
写入文件中的对象整体读取出来
那么我们去存储对象内容的时候
有的时候可能会想
有一些内容是很关键的
比如说密码
那么你直接就这么存出去了
会不会被盗取等等
我们可以有选择的说
有些数据成员
在对象序列化的时候不存它
那么我们就在这些数据成员前面
用transient去修饰
用transient修饰的成员
就不会被存入文件
另外static类型的变量
因为它不属于任何一个对象
所以我们将对象去序列化的时候
也不会存储static类型的变量
那么出于安全的考虑
Java的语法中规定
你要想实现对象的序列化
这个对象所属的类就必须去实现
Serializable接口
好
现在我们来看用ObjectOutputStream
去写对象的具体方法
我们当然要构造
一个ObjectOutputStream对象的话
也必须用另外一个
输出流对象作为参数
因为这个类它也是一个处理流
它不是直接执行写操作的
所以我们看到这里举一个例子
就是首先构造一个
FileOutputStream对象
这个对象是直接与文件打交道的
直接进行写的
在这个基础之上
以这个对象作为参数
构造一个ObjectOutputStream对象
然后我们就可以
用这个对象去将内存中的对象整体存盘
比如说我们这例子里面
是将这个String对象
比如说双引号里面Today
它就是个String对象
将String对象存到文件中去
第二句是构造一个日期对象
然后也将它存到文件中去
然后调用flush清空一下缓冲区
刚才说了你要执行对象的序列化
要去实现这个Serializable接口
这些对象String对象Date对象
它都已经是实现过
Serializable接口的了
同样如果我们想用这个ObjectInputStream对象
从文件中把以前存的对象数据
整体读进来的话
也需要首先有一个基础的
FileInputStream对象作为参数
然后我们才可以构造这个ObjectInputStream
因为ObjectInputStream
它也是一个处理流
不是直接去实现这个读操作的
好
构造了这样的
ObjectInputStream对象以后
我们就可以调用
它的readObject方法
将以前存在文件中的对象
这样读取出来放到内存里面来
刚才的例子中都是
读写预定义好的这些类的对象
那么这些没有问题
如果我们自己声明的类的对象
也需要整体存文件整体读取出来
那么我们的类就要去实现这个Serializable接口
实际上负担并不重
这就是一个空接口而已
那么这里列出了
这个Serializable接口的典型的代码
实际上它里面什么都没有
所以我们只需要
在声明我们自己类的时候
加上implements Serializable就行了
它因为是空接口
没有什么必须要实现的方法
实际上这就是一个标记
我竖起了一个标记
表示我设计这个类的时候
就打算允许这个类的对象
能够整体写入磁盘
还有我们在定义
这个类的变量的时候
如果说某些变量
不希望将来序列化的时候
被存入磁盘的话
我们可以用transient
关键字来修饰这些成员变量
就阻止了它的序列化
下面我们来看这个例子
这个例题里面
创建了一个书籍对象
并且将它序列化写入文件中
这个例题中我们来验证一下
将对象整个写到文件中
再读回来的这个过程
那我们来设计一个book类
我们是希望这个书籍类的对象
可以整体存到文件中再读出来的
也就是说这个类的对象
要允许序列化的
所以我们需要
让它实现一个Serializable接口
那么实现了Serializable接口以后
实际上就是竖起了一个标记
它可以被序列化了
但是这个接口里面
并没有什么方法需要我们实现
所以也没有什么负担
接下来呢就是很简单的一个类
里面有些数据成员
id这个name author price
然后有构造方法
非常简单的一个类
那接下来我们就来看一下
怎么样对book类对象进行序列化
首先在主方法中构造一个book对象
然后我们要将这个对象
试图写到文件中去
这样的话我们就要
去构造一个关联磁盘文件的输出流
比如说文件名
我们随便起一个book.dat
在普通的输出流之外
就是接一个对象输出流
ObjectOutputStream
这样它就可以将对象整体写出了
它有一个writeObject方法
直接把book写出
如果就关闭这个输出流就可以了
这样对象就被存到文件中去了
那么接下来我们来试图把它读回来
这样就要构造一个关联的
book.dat的输入流对象
FileinputStream
在它的外面再接一个
ObjectInputStream
就能够识别你读入的字节流
信息里面哪些字节
它是构成了一个对象
好
那我们就调用它的readObject方法
读取出来就是一个
Object类型的对象
它是可以识别哪是对象的开始
能够一个对象一个对象的读
但是读出来以后
是什么类型的对象呢
它的返回类型
就是一个Object类型
那我们必须知道当初
我们存到这个文件里面去的
是什么类的对象
自己要有文档记录
否则的话你读进来就是Object
好
那我们知道它曾经是book对象
所以做一个类型转换
把它的引用转换成book类型
然后我们就可以
调用book类型的方法
或者是访问book类型
里面的这个数据成员了
这里我们是将book对象的
id name author price
都显示在显示器上了
这就是一个简单的对象
读写的这么一个例子
我们看显示器上
显示的内容是这样的
有关对象序列化
还有一个非常有用的接口
就是Externalizable接口
它是干什么的呢
我们想想这种场景
有的时候我们一方面
希望将整个对象整体存入磁盘
另一方面又不想让它就是原样存
比如说我们可能希望
有选择的存一些内容
或者呢经过转换去存
比如说我希望信息加密
我存的时候
先用一个什么加密算法
转换一下再存到磁盘上
这样保密作用更好
那么对应的我自己读取的时候
我再用反过来的解密算法
对信息进行解密
恢复到内存中进行处理
如果我们有这样的需求
你用默认的对象写和读的方法
就达不到这样的目的了
怎么办呢
我们可以去实现
这个Externalizable接口
实现这个接口
就可以定义我们自己的
对象整体写整体读的方法了
这个Externalizable接口
它实际上就是
实现了Serializable接口的
所以如果我们的类
去实现Externalizable接口的话
就不必再去实现Serializable接口了
因为它已经是它的超接口了
这个接口中有两个方法
一个是writExternal
一个是readExternal
我们可以在这两个方法中
按照我们自己的设计
去写如何将一个对象的数据
写到文件中
和如何从文件中
读取这个对象的数据
那么这两个方法是
我们实现接口的时候必须实现的
好
那么大家会有一个疑问
我们在ObjectOutputStream这个writeObject这个方法
又起什么作用呢
那么如果你实现的
Externalizable接口
当你要写对象和读对象的时候
你依然还是使用writeObject
readObject
只是这个时候
这个writeObject方法
只负责写入对象的标志
然后接下来就会
调用你自己写的读取writeExternal方法
同样这个readObject这个方法
也会调用你自己写的
这个readExternal方法
所以这种情况下
你就达到了对象写和读的定制
好
在这一节我们简单的了解了一下
如何进行对象的序列化
这一节内容就是这些
-1.0-导学
--1.0-导学
-1.1-Java与面向对象程序设计简介
--第一章 Java语言基础知识--1.1-Java与面向对象程序设计简介
-1.2-基本数据类型与表达式
-第一章 Java语言基础知识--1.2-基本数据类型与表达式
-1.3-数组
--1.3.1-数组
-第一章 Java语言基础知识--1.3-数组
-1.4-算法的流程控制
--第一章 Java语言基础知识--1.4-算法的流程控制
-1.5-第一章小结
-第一章编程练习题
-课件
--外部链接
-Java环境配置、Eclipse使用、Helloworld程序详解
--使用eclipse建立Java项目、编写和运行Java程序
-Java数据类型
--Java整数类型
--Java浮点类型
--数据类型实战
--数据类型转换
--Java强制类型转换精度损失示例与表达式中的数据类型转换
-Java数组
-Java变量
--Java的变量
-命令行参数
--命令行参数的介绍
-2.0-导学
--2.0-导学
-2.1-面向对象方法的特性
--第二章 类与对象--2.1-面向对象方法的特性
-2.2-1-类声明与对象创建
--第二章 类与对象--2.2-1-类声明与对象创建
-2.2-2-数据成员
--第二章 类与对象--2.2-2-数据成员
-2.2-3-方法成员
--第二章 类与对象--2.2-3-方法成员
-2.2-4-包
--2.2-4-包
--第二章 类与对象--2.2-4-包
-2.2-5-类的访问权限控制
--第二章 类与对象--2.2-5-类的访问权限控制
-2.3-1-对象初始化
--第二章 类与对象--2.3-1-对象初始化
-2.3-2-内存回收
--第二章 类与对象--2.3-2-内存回收
-2.4-枚举类
--2.4-枚举类
--第二章 类与对象--2.4-枚举类
-2.5-应用举例
--2.5-应用举例
-2.6-第2章小结
-第二章编程练习题
-课件
--第二章课件
-3.0-导学
--3.0-导学
-3.1.1-3.1.2-类继承的概念和语法
--第三章 类的重用--3.1.1-3.1.2-类继承的概念和语法
-3.1.3-隐藏和覆盖
--第三章 类的重用--3.1.3-隐藏和覆盖
-3.2-Object 类
--第三章 类的重用--3.2-Object 类
-3.3-终结类与终结方法
--第三章 类的重用--3.3-终结类与终结方法
-3.4-抽象类
--3.4-抽象类
--第三章 类的重用--3.4-抽象类
-3.5-泛型
--3.5-泛型
--第三章 类的重用--3.5-泛型
-3.6-类的组合
--3.6-类的组合
-3.7-小结
--3.7-小结
-第三章编程练习题
-课件
--课件
-4.0-导学
--导学
-4.1-接口
--接口
--第四章 接口与多态--4.1-接口
-4.2.1-4.2.2-类型转换
--类型转换
--第四章 接口与多态--4.2.1-4.2.2-类型转换
-4.2.3-方法的查找
--方法的查找
--第四章 接口与多态--4.2.3-方法的查找
-4.3-多态的概念
--多态的概念
--第四章 接口与多态--4.3-多态的概念
-4.4-多态的应用举例
--多态的应用举例
--第四章 接口与多态--4.4-多态的应用举例
-4.5-构造方法与多态性
--构造方法和多态性
--第四章 接口与多态--4.5-构造方法与多态性
-4.6-本章小结
--本章小结
-第四章编程作业
-课件
--课件
-5.0-导学
--5.0-导学
-5.1.1-5.1.2-异常处理的概念
--第五章 输入输出--5.1.1-5.1.2-异常处理的概念
-5.1.3-5.1.5-异常的处理
--第五章 输入输出--5.1.3-5.1.5-异常的处理
-5.2-输入输出流的概念
--输入输出流的概念
--第五章 输入输出--5.2-输入输出流的概念
-5.3.1-写文本文件
--写文本文件
--第五章 输入输出--5.3.1-写文本文件
-5.3.2-读文本文件
--读文本文件
--第五章 输入输出--5.3.2-读文本文件
-5.3.3-写二进制文件
--写二进制文件
--第五章 输入输出--5.3.3-写二进制文件
-5.3.4-读二进制文件
--读二进制文件
-5.3.5-File类
--File类
-5.3.6-处理压缩文件
--处理压缩文件
-5.3.7-对象序列化
--对象序列化
-5.3.8-随机文件读写
--随机文件读写
-5.4-本章小结
--本章小结
-课件
--课件
-6.0-导学
--导学
-6.1-Java集合框架介绍
--第六章 对象群体的组织--6.1-Java集合框架介绍
-6.2-主要接口及常用的实现类
--第六章 对象群体的组织--6.2-主要接口及常用的实现类
-6.3-常用算法
--常用算法
-6.4-数组实用方法
-6.5-基于动态数组的类型(Vector, ArrayList)
--基于动态数组的类型(Vector, ArrayList)
-6.6-遍历Collection
-6.7-Map接口及其实现
-6.8-第6章小结
--第6章小结
-课件
--课件
-7.0-导学
--导学
-7.1-绘图
--绘图
-7.2-Swing基础
--Swing基础
-7.3-Swing的层次
--Swing的层次
-7.4-布局管理
--布局管理
-7.5-内部类
--内部类
-7.6-事件处理的基本概念
-7.7-事件派发机制
--事件派发机制
-7.8-顶层容器
--7.8-顶层容器
-7.9-中间层容器(一)
-7.10-中间层容器(二)
-7.11-原子组件(一)
-7.12-原子组件(二)
-7.13-原子组件(三)
-7.14-其它Swing特性
-7.15-第7章小结
-课件
--课件