Jetez un oeil à la source de PrintStream.
Il possède deux références à l'enregistreur sous-jacent textOut
et charOut
, une base de caractères et une base de texte (quel que soit ce que cela signifie). En outre, il hérite d'une troisième référence au OutputStream basé sur un octet, appelé out
.
/**
* Track both the text- and character-output streams, so that their buffers
* can be flushed without flushing the entire stream.
*/
private BufferedWriter textOut;
private OutputStreamWriter charOut;
Dans la méthode close()
il ferme tous (textOut
est essentiellement la même que celle charOut
).
private boolean closing = false; /* To avoid recursive closing */
/**
* Close the stream. This is done by flushing the stream and then closing
* the underlying output stream.
*
* @see java.io.OutputStream#close()
*/
public void close() {
synchronized (this) {
if (! closing) {
closing = true;
try {
textOut.close();
out.close();
}
catch (IOException x) {
trouble = true;
}
textOut = null;
charOut = null;
out = null;
}
}
}
Maintenant, la partie intéressante est que charOut contient un (emballé) fait référence à la PrintStream lui-même (notez le init(new OutputStreamWriter(this))
dans le constructeur)
private void init(OutputStreamWriter osw) {
this.charOut = osw;
this.textOut = new BufferedWriter(osw);
}
/**
* Create a new print stream.
*
* @param out The output stream to which values and objects will be
* printed
* @param autoFlush A boolean; if true, the output buffer will be flushed
* whenever a byte array is written, one of the
* <code>println</code> methods is invoked, or a newline
* character or byte (<code>'\n'</code>) is written
*
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
*/
public PrintStream(OutputStream out, boolean autoFlush) {
this(autoFlush, out);
init(new OutputStreamWriter(this));
}
Ainsi, l'appel à close()
appellera charOut.close()
, qui à son tour appelle l'original close()
à nouveau, ce qui explique pourquoi nous avons le drapeau de fermeture pour couper court à la récursion infinie.
C'est quelque chose qu'un débogueur est bon pour. Placez un point d'arrêt dans la méthode close et vous devriez être en mesure de voir pourquoi il est appelé. –