5

このプログラムでは、3 番目の文字列は表示されません。なんで?

(この Java プログラムは、Ubuntu 10.10 上の Eclipse Indigo で実行されました。)

import java.io.PrintWriter;

public class Tester
{
    static void nested()
    {
        PrintWriter object2 = new PrintWriter(System.out, true);
        object2.println("second");
        object2.close(); // delete this line to make all strings print
    }

    public static void main(String[] args)
    {
        PrintWriter object1 = new PrintWriter(System.out, true);
        object1.println("first");
        Tester.nested();
        object1.println("third");
        object1.close();
    }
}
4

2 に答える 2

4

ネストされたPrintWriterを閉じると、埋め込まれたSystem.outストリームも閉じられます。これにより、それ以上の書き込みが防止されているように見えます (ただし、出力を飲み込むのではなく、実際には例外が発生することが予想されます)。

したがって、問題全体は次のように縮小できます。

public class Tester {

    public static void main(String[] args) {        
        System.out.println("first");
        System.out.close();
        System.out.println("second");        
    }
}

これも"first"の後に出力されなくなりましたが、例外もスローされません。非常に迅速なデバッグ セッションは、デバッグが少し難しい Sun ネイティブ関数への呼び出しがあることを示しています。

アップデート*

これが犯人です:System.outタイプjava.io.PrintStreamであり、次の素敵なメソッドが含まれています:

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;
    }
}

メソッドはensureOpen()確かに例外をスローしますが、ここでは飲み込まれ、troubleフラグが設定されます (よく知られているアンチパターン)。したがって、これは閉じられたストリームへのそれ以降の書き込みを黙って無視します。

于 2011-08-07T09:58:07.033 に答える
1

close()のドキュメントから、それは言う

ストリームを閉じ、それに関連付けられているすべてのシステム リソースを解放します。以前に閉じたストリームを閉じても効果がない

だから私の推測では、それは System.out を解放しているため、再び使用することはできません。また、最後に行を追加しましたが、コードでSystem.out.println("Finished");クローズが呼び出された場合、何も出力しません。System.outやってみて。

于 2011-08-07T09:59:34.030 に答える