Java™ 教程(对象流)

对象流

正如数据流支持原始数据类型的I/O同样,对象流也支持对象的I/O,大多数(但不是所有)标准类支持其对象的序列化,那些是实现标记接口Serializable的。html

对象流类是ObjectInputStreamObjectOutputStream,这些类实现ObjectInputObjectOutput,它们是DataInputDataOutput的子接口。这意味着数据流中涵盖的全部原始数据I/O方法也在对象流中实现,所以,对象流能够包含原始值和对象值的混合。ObjectStreams示例说明了这一点,ObjectStreams建立与DataStreams相同的应用程序,并进行了一些更改,首先,价格如今是BigDecimal对象,以更好地表明小数值,其次,将Calendar对象写入数据文件,指示发票日期。java

若是readObject()没有返回预期的对象类型,则尝试将其强制转换为正确的类型可能会抛出ClassNotFoundException,在这个简单的例子中,这不可能发生,所以咱们不会尝试捕获异常,相反,咱们经过向main方法的throws子句添加ClassNotFoundException来通知编译器咱们已经意识到了这个问题。git

复杂对象的输出和输入

writeObjectreadObject方法易于使用,但它们包含一些很是复杂的对象管理逻辑,这对像Calendar这样的类来讲并不重要,它只封装了原始值,可是许多对象包含对其余对象的引用,若是readObject是要从流重建一个对象,它必须可以重建原始对象所引用的全部对象,这些附加对象可能有本身的引用,依此类推。在这种状况下,writeObject遍历整个对象引用网络,并将该网络中的全部对象写入流,所以,对writeObject的单个调用可能致使将大量对象写入流。github

下图演示了这一点,其中调用writeObject来写入名为a的单个对象,该对象包含对象bc的引用,而b包含对de的引用,调用writeobject(a)不只写入a,并且写入重建a所需的全部对象,所以该网络中的其余四个对象也被写入。当readObject读回a时,也会读回其余四个对象,并保留全部原始对象引用。segmentfault

io-trav.gif

你可能想知道若是同一个流上的两个对象都包含对单个对象的引用会发生什么,当他们被回读时,他们都会引用一个对象吗?答案是确定的。一个流只能包含一个对象的副本,尽管它能够包含对该对象的任意数量的引用,所以,若是你明确地将对象写入流两次,那么你实际上只写入了两次引用,例如,若是如下代码将对象ob写入流两次:api

Object ob = new Object();
out.writeObject(ob);
out.writeObject(ob);

每一个writeObject都必须与readObject匹配,所以读回流的代码将以下所示:网络

Object ob1 = in.readObject();
Object ob2 = in.readObject();

这产生两个变量ob1ob2,它们是对单个对象的引用。oracle

可是,若是将单个对象写入两个不一样的流,则会有效地复制它 — 读取两个流的单个程序将看到两个不一样的对象。spa


上一篇:数据流

相关文章
相关标签/搜索