【问题标题】:why does a local PrintWriter interfere with another local PrintWriter?为什么本地 PrintWriter 会干扰另一个本地 PrintWriter?
【发布时间】:2011-08-07 09:51:39
【问题描述】:

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

(此 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();
    }
}

【问题讨论】:

    标签: java console printwriter


    【解决方案1】:

    通过关闭嵌套的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 类型,它包含以下 lovely 方法:

    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 标志(众所周知的反模式)。因此,这会默默地忽略对关闭流的进一步写入。

    【讨论】:

      【解决方案2】:

      从close() 的文档中说

      关闭流并释放与 它。关闭之前关闭的流没有效果

      所以我的猜测是它正在释放 System.out,因此不能再次使用。另外,我在末尾添加了一个System.out.println("Finished"); 行,如果在代码中对System.out 调用了关闭,它不会输出任何内容。试试看。

      【讨论】:

        猜你喜欢
        • 2011-08-11
        • 2017-09-19
        • 2017-02-21
        • 2011-12-08
        • 2019-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-25
        相关资源
        最近更新 更多