开发者

why does a local PrintWriter interfere with another local PrintWriter?

开发者 https://www.devze.com 2023-03-26 05:32 出处:网络
In this program, the third string never gets printed.Why? (This Java program was run on Eclipse Indigo on Ubuntu 10.10.)

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开发者_JS百科 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();
    }
}


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消