对象流
正如数据流支持原始数据类型的I/O一样,对象流也支持对象的I/O,大多数(但不是全部)标准类支持其对象的序列化,那些是实现标记接口Serializable的。
对象流类是ObjectInputStream和ObjectOutputStream,这些类实现ObjectInput和ObjectOutput,它们是DataInput和DataOutput的子接口。这意味着数据流中涵盖的所有原始数据I/O方法也在对象流中实现,因此,对象流可以包含原始值和对象值的混合。ObjectStreams示例说明了这一点,ObjectStreams创建与DataStreams相同的应用程序,并进行了一些更改,首先,价格现在是BigDecimal对象,以更好地代表小数值,其次,将Calendar对象写入数据文件,指示发票日期。
如果readObject()没有返回预期的对象类型,则尝试将其强制转换为正确的类型可能会抛出ClassNotFoundException,在这个简单的例子中,这不可能发生,因此我们不会尝试捕获异常,相反,我们通过向main方法的throws子句添加ClassNotFoundException来通知编译器我们已经意识到了这个问题。
复杂对象的输出和输入writeObject和readObject方法易于使用,但它们包含一些非常复杂的对象管理逻辑,这对像Calendar这样的类来说并不重要,它只封装了原始值,但是许多对象包含对其他对象的引用,如果readObject是要从流重建一个对象,它必须能够重建原始对象所引用的所有对象,这些附加对象可能有自己的引用,依此类推。在这种情况下,writeObject遍历整个对象引用网络,并将该网络中的所有对象写入流,因此,对writeObject的单个调用可能导致将大量对象写入流。
下图演示了这一点,其中调用writeObject来写入名为a的单个对象,该对象包含对象b和c的引用,而b包含对d和e的引用,调用writeobject(a)不仅写入a,而且写入重建a所需的所有对象,因此该网络中的其他四个对象也被写入。当readObject读回a时,也会读回其他四个对象,并保留所有原始对象引用。
你可能想知道如果同一个流上的两个对象都包含对单个对象的引用会发生什么,当他们被回读时,他们都会引用一个对象吗?答案是肯定的。一个流只能包含一个对象的副本,尽管它可以包含对该对象的任意数量的引用,因此,如果你明确地将对象写入流两次,那么你实际上只写入了两次引用,例如,如果以下代码将对象ob写入流两次:
Object ob = new Object(); out.writeObject(ob); out.writeObject(ob);
每个writeObject都必须与readObject匹配,因此读回流的代码将如下所示:
Object ob1 = in.readObject(); Object ob2 = in.readObject();
这产生两个变量ob1和ob2,它们是对单个对象的引用。
但是,如果将单个对象写入两个不同的流,则会有效地复制它 — 读取两个流的单个程序将看到两个不同的对象。
上一篇:数据流文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72988.html
Java™ 教程 Java教程是为JDK 8编写的,本页面中描述的示例和实践没有利用在后续版本中引入的改进。 Java教程是希望使用Java编程语言创建应用程序的程序员的实用指南,其中包括数百个完整的工作示例和数十个课程,相关课程组被组织成教程。 覆盖基础知识的路径 这些教程以书籍的形式提供,如Java教程,第六版,前往Amazon.com购买。 入门 介绍Java技术和安装Java开发软件并使用...
命令行I/O 程序通常从命令行运行,并在命令行环境中与用户交互,Java平台以两种方式支持这种交互:通过标准流和控制台。 标准流 标准流是许多操作系统的一个特性,默认情况下,它们从键盘读取输入并将输出写入显示器,它们还支持文件和程序之间的I/O,但该功能由命令行解释器控制,而不是程序。 Java平台支持三种标准流:标准输入,可通过System.in访问;标准输出,可通过System.out访问;和...
缓冲流 到目前为止,我们看到的大多数示例都使用无缓冲的I/O,这意味着每个读取或写入请求都由底层操作系统直接处理,这可以使程序效率低得多,因为每个这样的请求通常触发磁盘访问、网络活动或一些相对昂贵的其他操作。 为了减少这种开销,Java平台实现了缓冲的I/O流,缓冲输入流从称为缓冲区的内存区读取数据,仅当缓冲区为空时才调用原生输入API,类似地,缓冲输出流将数据写入缓冲区,并且仅在缓冲区已满时才调...
数据流 数据流支持原始数据类型值(boolean、char、byte、short、int、long、float和double)以及String值的二进制I/O,所有数据流都实现DataInput接口或DataOutput接口,本节重点介绍这些接口最广泛使用的实现,DataInputStream和DataOutputStream。 DataStreams示例通过写出一组数据记录,然后再次读取它们来演...
格式化流 实现格式化的流对象是PrintWriter(字符流类)或PrintStream(字节流类)的实例。 你可能需要的唯一PrintStream对象是System.out和System.err(有关这些对象的更多信息,请参阅命令行中的I/O),当你需要创建格式化的输出流时,请实例化PrintWriter,而不是PrintStream。 与所有字节和字符流对象一样,PrintStream和Pri...
阅读 1844·2021-11-17 09:33
阅读 6356·2021-10-12 10:20
阅读 2272·2021-09-22 15:50
阅读 1750·2021-09-22 15:10
阅读 571·2021-09-10 10:51
阅读 579·2021-09-10 10:50
阅读 2884·2021-08-11 11:19
阅读 1742·2019-08-30 15:55