public PrintWriter(OutputStream out, boolean autoFlush):
out - An output stream autoFlush - A boolean; if true, the println, printf, or format methods will flush the output buffer
public PrintStream(OutputStream out, boolean autoFlush):
out - The output stream to which values and objects will be printed autoFlush - A boolean; if true, the output buffer will be flushed whenever a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written
What was the reason for changing autoflush logic between these classes?
Because they are always considered as identical except for encoding moments and "autoflush" without flushing on print()
hardly corresponds to principle of least astonishment, silly bugs occur:
I created a PrintWriter with autoflush on; why isn't it autoflushing?
I think the answer lies in the history of Java. The trio InputStream
, OutputStream
and PrintStream
in java.io
date back to Java 1.0. That is before serious support for file encodings and character sets were built into the language.
To quote the Javadoc:
"A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently. Two other features are provided as well. Unlike other output streams, a PrintStream never throws an IOException; instead, exceptional situations merely set an internal flag that can be tested via the checkError method..."
To summarize, it is a convenience for generating textual output, grafted on top of lower level IO.
In Java 1.1, Reader
, Writer
and PrintWriter
were introduced. Those all support character sets. While InputStream
and OutputStream
still had a real uses (raw data processing), PrintStream
became far less relevant, because printing by nature is about text.
The Javadoc for PrintWriter
explicitly states:
Unlike the PrintStream class, if automatic flushing is enabled it will be done only when one of the println() methods is invoked, rather than whenever a newline character happens to be output. The println() methods use the platform's own notion of line separator rather than the newline character.
Put another way, PrintWriter should only be used through the print*(...)
APIs, because writing newline characters etc should not be the caller's responsibility, the same way dealing with file encodings and character sets are not the caller's responsibility.
I would argue that PrintWriter
should have been java.io.Printer
instead, and not have extended Writer
. I don't know whether they extended to mimic PrintStream
, or because they were stuck on maintaining the pipe design idiom.
The reason it wasn't the same at start was probably just an accident. Now it's backwards compatibility.
来源:https://stackoverflow.com/questions/5492405/printwriter-autoflush-puzzling-logic