Reputation: 121800
System.out
and System.err
are both PrintStream
s; and PrintStream
extends FilterOutputStream
.
From the FilterOutputStream
's javadoc:
This class is the superclass of all classes that filter output streams. These streams sit on top of an already existing output stream (the underlying output stream) which it uses as its basic sink of data, but possibly transforming the data along the way or providing additional functionality.
The class FilterOutputStream itself simply overrides all methods of OutputStream with versions that pass all requests to the underlying output stream. Subclasses of FilterOutputStream may further override some of these methods as well as provide additional methods and fields.
(emphasis mine)
FilterOutputStream
itself extends OutputStream
.
I am at a loss here. Is there any reason why PrintStream
needs to extend FilterOutputStream
instead of OutputStream
?
Sample code appreciated...
Upvotes: 4
Views: 533
Reputation: 117655
FilterOutputStream
applies the composition pattern where it delegates all the calls to its instance variable out
:
/* The underlying output stream to be filtered. */
protected OutputStream out;
FilterOutputStream
also has default implementations for the abstract class OutputStream
:
public void write(int b) throws IOException {
out.write(b);
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
throw new IndexOutOfBoundsException();
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
Now, any class including PrintStream
can extend FilterOutputStream
and override the appropriate methods. Note that they still need to delegate their calls to out
. For example PrintStream#flush()
:
public void flush() {
synchronized (this) {
try {
ensureOpen();
out.flush();
}
catch (IOException x) {
trouble = true;
}
}
}
Upvotes: 2
Reputation: 41281
The PrintStream must implement various filters, handling character encodings, and most ultimately, printing non-character data as characters.
The general contract of FilterOutputStream fits this best, so that is the class used.
Upvotes: 1
Reputation: 285405
Any higher level Stream that needs to filter the input or output of a nested lower-level Stream, needs to first extend FilteredOutputStream, and the same is true for InputStreams. So it makes sense that all of the higher-level OutputStreams extend the FilteredOutputStream class, in other words, all Streams that allow for and in fact require the nesting of other Streams to function, must extend this class.
I don't know what the class does internally, but I imagine it somehow massages the data to allow the higher level streams to be able to make sense out of them. To know more, I'm guessing that you're going to have to delve into the source code.
Upvotes: 0