5

在这个程序中,第三个字符串永远不会被打印出来。为什么?

(这个 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

通过关闭 nested 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 回答