Somewhat to my surprise, the following code prints out “Close” twice. Running through the debugger, it seems MyPrintStream.close() calls super.close(), which ends up calling MyPrintStream.close() again.
import java.io.*;
public class PrintTest
{
static class MyPrintStream extends PrintStream
{
MyPrintStream(OutputStream os)
{
super(os);
}
@Override
public void close()
{
System.out.println("Close");
super.close();
}
}
public static void main(String[] args) throws IOException
{
PrintStream ps = new MyPrintStream(new FileOutputStream(File.createTempFile("temp", "file")));
ps.println("Hello");
ps.close();
}
}
Why is this happening? Should I not be extending PrintStream?
Take a look at PrintStream’s source.
It has two references to the underlying Writer
textOutandcharOut, one character-base, and one text-based (whatever that means). Also, it inherits a third reference to the byte-based OutputStream, calledout.In the
close()method it closes all of them (textOutis basically the same ascharOut).Now, the interesting part is that charOut contains a (wrapped) referenced to the PrintStream itself (note the
init(new OutputStreamWriter(this))in the constructor )So, the call to
close()will callcharOut.close(), which in turn calls the originalclose()again, which is why we have the closing flag to cut short the infinite recursion.