Head First Java(4)—— 序列化和文件的输入/输出

来源:互联网 发布:mysql自增长主键使用 编辑:程序博客网 时间:2024/05/16 05:13

14 序列化和文件的输入/输出

序列化(Serialization):将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象~!!


存储装填的选择很多,要看你如何使用储存下来的状态而决定:

1. 如果只有自己写的Java程序会用到这些数据:用序列化(serialization)

将被序列化的对象写到文件中,就可以让你的程序去文件中读取序列化的对象并把它们展开回到活生生的状态。

2. 如果数据需要被其他程序引用:

写一个纯文本文件。用其他程序可以解析的特殊字符写到文件中。

串流要两两连接才能作出有意义的事情——其中一个表示连接,另一个则是被调用方法的。  连接的串流通常都是很低层的。

为何不以单一的串流来执行?

考虑到良好的面向对象设计。每个类只要做好一件事。FileOutputStream把字节写入文件。ObjectOutputStream把对象转换成可以写入串流的数据。当我们调用ObjectOutputStream的WriteObject事,对象会被打成串流送到FileOutputStream来写入文件。




对象序列化的关键:  堆上是否有与存储时一摸一样的对象状态。

当对象被序列化时,被该对象引用的实例变量也会被序列化。且所有被引用的对象也会被序列化,这些操作时自动进行的。


如果要让类能够被序列化,就实现Serializable。Serializable接口又被称为maker或tag类的标记用接口,因为此接口并没有任何方法需要实现。它的唯一目的就是声明有实现它的类是可以被序列化的。如果某类是可序列化的,则它的子类也自动地可以序列化。


objectOutputStream.writeObject(myBox);  任何放在此处的对象都必须要实现序列化。(应该是可实现序列化的??


真个对象版图都必须正确的序列化,不然就得全部失败。即序列化是个boolean类型,非success即failed

如果某实例变量不能或不应该被实例化,就把它标记为transient

eg: transient String currentID

如果你把某个对象序列化,transient的引用实例变量会以null返回,而不管存储当时它的值是什么。这代表整个对象版图中连接到该特定实例变量的部分不会被存储。


父类不能序列化,子类可以被序列化。(如果父类是可以被继承的,没有被标记为final,就可以制作出可被序列化的子类)。父类可序列化,子类继承,也可序列化。        简单讲,当对象被还原且它的父类不可序列化时,父类的构造函数会跟创建新的对象一样地执行。如果类没有什么好理由不能被序列化,制作可序列化的子类会是个好方法。


反序列化(解序列化)deserialization


与文件相连的是FileInputStream ,与对象相连的是ObjectInputStream。

为何要加载类??(如果找不到或无法加载类则Java虚拟机会抛出异常)

如果对象在继承树上有个不可序列化的祖先类,则该不可序列化类以及在它之上的类地构造函数就会执行。一旦构造函数连锁启动之后将无法停止。也就是说,从第一个不可序列化的父类开始,全部都会重新初始状态。


静态变量会被序列化嚒?

不会。static代表“每个类一个”而不是“每个对象一个”。当对象被还原时,静态变量会维持类中原本的样子,而不是存储时的样子。


写序列化对象:objectOutputStream.writeObject(someObject);

写字符串:fileWriter.write("My first String to save");


输入/输出相关的操作都必须包在try/catch块中。如下是写字符串:



java.io.File :   File这个类代表磁盘上的文件,但不是文件中的内容,可以把File对象想象成文件的路径,而不是文件本身。


BufferedWriter writer = new BufferedWriter(new FileWriter(aFile));

如果想要强制缓冲区立即写入,只要调用writer.flush()这个方法就可以要求缓冲区马上把内容写下去。


使用serialVersionUID:每当对象被序列化的同时,该对象都会被“盖”上一个类地版本识别ID,成为serialVersionUID,它是根据类地结构信息计算出来的。如果你认为类有可能会演化,就把版本识别ID放在类中。把serialVersionID放在class中,让类在演化的过程中还维持相同的ID。