ObjectInputStream 不应该扩展 FilterInputStream 吗?
块引用来自 Java 文档 -
FilterInputStream 包含一些 其他输入流,它用作 它的基本数据来源,可能 沿途转换数据或 提供附加功能。
DataInputStream 允许 应用程序读取原始Java数据 来自底层输入流的类型 以独立于机器的方式。
因此,DataInputStream
扩展了 FilterInputStream
ObjectInputStream 反序列化 先前的原始数据和对象 使用 ObjectOutputStream 编写。
然而,由于某种原因,ObjectInputStream
不会扩展 FilterInputStream
,即使它也从底层输入流读取对象(这次不是原始类型)。这是相关类的分支。
是否有相同的设计推理?
The block quotes are from the Java Docs -
A FilterInputStream contains some
other input stream, which it uses as
its basic source of data, possibly
transforming the data along the way or
providing additional functionality.A DataInputStream lets an
application read primitive Java data
types from an underlying input stream
in a machine-independent way.
The DataInputStream
therefore extends FilterInputStream
An ObjectInputStream deserializes
primitive data and objects previously
written using an ObjectOutputStream.
However, for some reason the ObjectInputStream
does NOT extend FilterInputStream
even though it is also reading objects (this time and not primitive types) from the underlying input stream. Here is the branching of the concerned classes.
Is there is a design reasoning for the same?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
明智的问题。考虑到这一点,我相信
Object*Stream
可以被设计为扩展Filter*Stream
(这同样适用于Output或Input)。为什么没有这样做?也许是因为:它没有带来真正的好处。正如 Maciej 所解释的,
Filter*Stream
的要点,除了一些不重要的组织类之外,是提供一些常见的默认(相当琐碎)实现< /strong> 具有该模式的那些类(从某些底层流读/写,最终转换流),由其他类(来自 Java API 或用户)扩展。但是Filter*Stream
与接口无关:您几乎永远不会找到或实现某些需要Filter*Stream
作为参数的方法,例如例子。因此,当有替代方案时,让类继承*Stream
或Filter*Stream
的决定主要是一个实现决策;该类的用户基本上不会关心。ObjectOutputStream
的设计者决定为那些愿意扩展该类的人提供额外的灵活性,通过提供额外的 空构造函数(没有底层OuputStream
)。此功能(我认为相当罕见)使该类(在概念上和实现方面)与Filter*Stream
类相距甚远。同样,这似乎并不是决定性的。Sensible question. Thinking of it, I believe that
Object*Stream
could have been designed to extendFilter*Stream
(the same applies to Output or Input). Why it wasn't done so? Perhaps because:It gives no real benefit. As explained by Maciej, the point of
Filter*Stream
, apart from some unimportant organization of classes, is to provide some common default (and rather trivial) implementation of those classes that have that pattern (read/write from some underlying stream, eventually transforming the stream), to be extended by other classes (from Java API or user). ButFilter*Stream
is not about interfaces : you'll almost never find or implement some method that requires aFilter*Stream
as argument, for example. Hence, the decision of making a class inherit*Stream
orFilter*Stream
, when there is the alternative, is mostly an implementation decision; the users of the class will basically not care.The designers of
ObjectOutputStream
decided to give extra flexibility to those willing to extend the class, totally reimplementing it, by giving an extra empty constructor (with no underlyingOuputStream
). This feature (rather rare, I think) puts the class (conceptually and implementation wise) a litte far apart theFilter*Stream
class. Again, this does not seem conclusive.两者之间存在区别:
逻辑上
LinkedList
不是AbstractList
,因为它不是抽象的。然而,从代码的角度来看,共享List
方法的一些实现是有益的,因为它们可以根据其他方法来实现,通常具有相同的效率(例如isEmpty
可以实现为size() == 0
)。某些平台,例如 GObject(或在某种程度上扩展了 Haskell - 尽管它不是 OO 语言并且许多东西完全不同)允许定义它的接口中方法的默认实现。
然而,Java 的情况并非如此,它使用
Abstract*
类来重用代码。Filter*Stream
并不是定义输出被发送到某个地方(因为 Java I/O 的重点是生产者/接收者不关心),而是用于重用公共代码。There is distinction between:
Logically
LinkedList
is notAbstractList
as it is not abstract. However from the code point of view it is benefitial to share some implementation ofList
methods as they can be implement in terms of others, usually with the same efficiency (for exampleisEmpty
can be implemented assize() == 0
).Some platforms, such as GObject (or to some extend Haskell - although it is not OO language and many things are totally different) alows default implementation of methods in interface which is defining it.
However it is not the case with Java which uses
Abstract*
classes to reuse the code.Filter*Stream
is not so much defining that the output is sent somewhere (as the whole point of the Java I/O is that the produer/reciver does not care) but it is used to reuse common code.我猜想 ObjectInputStream 必须重写 FilterInputStream 的每个方法。
当你这样做时,维持这种关系就没有什么意义了。
重要的是:ObjectInputStream 是一个InputStream(除了其他方法之外,您仍然可以向其中写入原始数据)并且存在这种关系。
I guess ObjectInputStream had to override every method of FilterInputStream.
When you do this there is not really a point of maintaining that relationship.
What's important: ObjectInputStream IS an InputStream ( you still can write primitive data to it in addition to other methods ) and that relationship is there.