Question:
After FilterInputStream
through the documentation and source code of the FilterInputStream
class, as well as the code of its heirs, the question arose: why do we need this class at all?
Because Since this class is not a data source, does not perform any useful work, then probably the only purpose of its existence is to solve some architectural problems.
As I understand it now, the java.io I / O system uses the decorator pattern. If classes inherited from FilterInputStream
need to delegate some of the behavior to the input stream, a reference to which they accept in their constructor, they do not refer to the FilterInputStream
methods, but call these methods immediately from this reference. The only thing in FilterInputStream
that is used by all of its descendants is the protected volatile InputStream in
reference field. But this is just one single field and it is not at all difficult to declare it in the descendants of FilterInputStream
themselves.
Please, tell me whether I am right or not, and if not, then what I am wrong or what I did not take into account.
Answer:
The only thing in
FilterInputStream
that is used by all of its descendants is the protected volatile InputStream in reference field.
In order, everything that FilterInputStream
does:
- contains an
in
field that descendants can use; - declares a constructor that accepts an
InputStream
– each inheritor will have to declare at least one constructor and call theFilterInputStream
constructor; - creates default implementations for all
InputStream
methods, delegating them to a nested stream — nine methods that inheritors may not override.
Those. if there was no FilterInputStream
each of its heirs would have to:
- declare a field for a nested stream;
- accept a stream in the constructor and initialize the field;
-
create template implementations for all
InputStream
methods of the form:public int read() { return in.read(); }
Due to the presence of template implementations, the inheritor can override only those methods whose behavior is specific to the inheritor. For example, CheckedInputStream
overrides three FilterInputStream
methods and inherits six.
The documentation lists 11 heirs to FilterInputStream
(this is only in the standard library). Duplicating the field and initialization would already be bad. It is unacceptable to insert the same delegating methods into each of the classes.