为什么本地 PrintWriter 会干扰另一个本地 PrintWriter?

发布于 2024-11-28 16:55:54 字数 615 浏览 4 评论 0原文

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

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

In this program, the third string never gets printed. Why?

(This Java program was run on Eclipse Indigo on Ubuntu 10.10.)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

煞人兵器 2024-12-05 16:55:54

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

By closing the nested PrintWriter, you also close the embedded System.out stream, which seemingly prevents further writes to it (although I would expect an exception really instead of swallowing output).

So the entire problem can be reduced to:

public class Tester {

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

This too doesn't print anymore after "first", but also doesn't throw an exception. A very quick debugging session shows there's a call to a Sun native function, which is a little harder to debug into.

Update*

This is the culprit: System.out is of type java.io.PrintStream and it contains the following lovely method:

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

The ensureOpen() method indeed throws an exception, but it's swallowed here and the trouble flag is set (a well known anti-pattern). This thus silently ignores further writes to the closed stream.

一杯敬自由 2024-12-05 16:55:54

来自 close() 的文档 它说

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

所以我的猜测是它正在释放 System.out,因此不能再次使用。另外,我在末尾添加了 System.out.println("Finished"); 行,如果在 System.out 在代码中。尝试一下。

From the documentation of close() it says

Closes the stream and releases any system resources associated with
it. Closing a previously closed stream has no effect

So my guess is that it is releasing the System.out and hence can't be used again. Also, I added a System.out.println("Finished"); line at the end and it doesn't output anything if a close has been called on System.out in the code. Try it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文