PrintStream のドキュメントから:
オプションで、自動的にフラッシュするように PrintStream を作成できます。これは、バイト配列が書き込まれた後、 println メソッドの 1 つが呼び出された後、または改行文字またはバイト ('\n') が書き込まれた後に、 flush メソッドが自動的に呼び出されることを意味します。
次に、与えられたコード
System.out.print("hi"); // gives console output: hi
System.out.print(7); // gives console output: 7
// prevents flushing when stream wiil be closed at app shutdown
for (;;) {
}
コンソールに出力が表示されるのはなぜですか? これまで何もフラッシュされないため、コンソール(System.out からの PrintStream インスタンス) には何も書き込まれません。
これはこれに答えませんでした。
答えはソース コード (プライベート ユーティリティ メソッド BufferedWriter.flushBuffer()) にあると思いますが、コードへのコメントがわかりません。「ストリーム自体をフラッシュせずに、出力バッファを基になる文字ストリームにフラッシュします」: 「ストリーム自体」である PrintStream (コンソール出力に関連付けられている) がフラッシュされない場合、コンソールへの出力は更新されません!...
PrintStream.print(String) のソース:
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
BufferedWriter.flushBuffer() のソース:
/**
* Flushes the output buffer to the underlying character stream, without
* flushing the stream itself. This method is non-private only so that it
* may be invoked by PrintStream.
*/
void flushBuffer() throws IOException {
synchronized (lock) {
ensureOpen();
if (nextChar == 0)
return;
out.write(cb, 0, nextChar);
nextChar = 0;
}
}
詳細はこちらにも記載されています。非常に複雑ですが、ある段階で BufferedWriter が PrintStream コンストラクターに渡されるようです。