为什么本地 PrintWriter 会干扰另一个本地 PrintWriter?
在此程序中,第三个字符串永远不会被打印。为什么?
(该 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过关闭嵌套的 PrintWriter,您还可以关闭嵌入的 System.out 流,这似乎阻止了对其的进一步写入(尽管我希望真正出现异常而不是吞噬输出) 。
所以整个问题可以简化为:
在“first”之后也不再打印,但也不会抛出异常。非常快速的调试会话显示存在对 Sun 本机函数的调用,这有点难以调试。
更新*
这就是罪魁祸首:
System.out
的类型为java.io.PrintStream
并且它包含以下内容可爱 方法:ensureOpen()
方法确实抛出异常,但它在这里被吞没,并且设置了trouble
标志(众所周知的反模式)。因此,这会默默地忽略对关闭流的进一步写入。By closing the nested
PrintWriter
, you also close the embeddedSystem.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:
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 typejava.io.PrintStream
and it contains the following lovely method:The
ensureOpen()
method indeed throws an exception, but it's swallowed here and thetrouble
flag is set (a well known anti-pattern). This thus silently ignores further writes to the closed stream.来自 close() 的文档 它说
所以我的猜测是它正在释放 System.out,因此不能再次使用。另外,我在末尾添加了
System.out.println("Finished");
行,如果在System.out
在代码中。尝试一下。From the documentation of close() it says
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 onSystem.out
in the code. Try it out.