P429-P446
《Head First Java》20201024读书笔记
第14章 序列化和文件的输入/输出
对象可以被序列化也可以展开。
储存对象
把数据写到某处,这可能是个磁盘上的文件,或者是来自网络上的串流。
此处谈论不涉及使用数据库的情况。
- 如果只有自己写的Java程序会用到这些数据:
用序列化
将被序列化的对象写到文件中。然后就可以让你的程序去文件中读取序列化的对象并把它们展开回到活生生的状态。 - 如果数据需要被其他程序引用:
写一个纯文本文件。
用其他程序可以解析的特殊字符写到文件中。例如写成用tab字符来分隔的档案以便让电子表格或数据库应用程序能够应用。
将序列化对象写入文件
- 数据在串流中移动
将串流连接起来代表来源与目的地(文件或网络端口)的连接。
串流必须要连接到某处才能算是个串流。
- 序列化程序会将对象版图上的所有东西存储起来。 被对象的实例变量所引用的所有对象都会被序列化。
- 如果要让类能够被序列化,就实现Serializable。
Serializable接口又被称为marker或tag类的标记用接口,因为此接口并没有任何方法需要实现的。
它的唯一目的就是声明有实现它的类是可以被序列化的,也就是说,此类型的对象可以通过序列化的机制来存储。如果某类是可序列化的,则它的子类也自动地可以序列化。
- 如果某实例变量不能或不应该被序列化,就把它标记为transient(瞬时)的。
- 解序列化(Deserialization):还原对象
对象的序列化
- 可以通过序列化来存储对象的状态。
- 使用ObjectOutputStream来序列化对象(java.io)。
- Stream是连接串流或是链接用的串流。
- 连接串流用来表示源或目的地、文件、网络套接字连接。
- 链接用串流用来衔接连接串流。
- 用FileOutputStream链接ObjectOutputStream来将对象序列化到文件上。
- 调用ObjectOutputStream的writeObject(theObject)来将对象序列化,不需调用FileOutputStream的方法。
- 对象必须实现序列化这个接口才能被序列化。如果父类实现序列化,则子类也就自动地有实现,而不管是否有明确的声明。
- 当对象被序列化时,整个对象版图都还会被序列化。这代表它的实例变量所引用的对象也会被序列化。
- 如果有不能序列化的对象,执行期间就会抛出异常。
- 除非该实例变量被标记为transient。否则,该变量在还原的时候会被赋予null或primitive主数据类型的默认值。
- 在解序列化时,所有的类都必须能让Java虚拟机找到。
- 读取对象的顺序必须与写入顺序相同。
- readObject()的返回类型是Object,因此解序列化回来的对象还需要转换成原来的类型。
- 静态变量不会被序列化,因为所有对象都是共享同一份静态变量值。