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?
No. It is not require to close other components.
The close() method of PrintStream Class in Java is used to close the stream. Closing a stream deallocates any value in it or any resources associated with it. The PrintStream instance once closed won't work. Also a PrintStream instance once closed cannot be closed again.
A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently. Unlike other output streams, a PrintStream never throws an IOException; instead, exceptional situations merely set an internal flag that can be tested via the checkError method.
The primary difference is that PrintStream writes raw bytes in the machine's native character format, and PrintWriter converts bytes to recognized encoding schemes. Thus, files created with PrintWriter are more compatible across different platforms than files created with PrintStream .
If you look at your code in a debugger and set a breakpoint in the close()
method, it'll reveal the stacktraces of who is calling your close()
method:
the complete stacktrace for the latter looks like:
PrintTest$MyPrintStream.close() line: 20
sun.nio.cs.StreamEncoder$CharsetSE.implClose() line: 431 [local variables unavailable]
sun.nio.cs.StreamEncoder$CharsetSE(sun.nio.cs.StreamEncoder).close() line: 160 [local variables unavailable]
java.io.OutputStreamWriter.close() line: 222 [local variables unavailable]
java.io.BufferedWriter.close() line: 250 [local variables unavailable]
PrintTest$MyPrintStream(java.io.PrintStream).close() line: 307
PrintTest$MyPrintStream.close() line: 20
PrintTest.main(java.lang.String[]) line: 27
Sadly though I can't tell why StreamEncoder would call back into your PrintStream though, as my IDE doesn't have a source attachment for sun.nio.cs.StreamEncoder :( This is JDK 6 btw, if that matters.
By the way, if you are asking this question because you noticed that custom code in your close()
method is running twice, you should really be checking if this.closing
. PrintStream.close()
sets this to true (and the class's comments state /* To avoid recursive closing */
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With