2011-08-07 10 views
5

En este programa, la tercera cadena nunca se imprime. ¿Por qué?¿por qué un PrintWriter local interfiere con otro PrintWriter local?

(Este programa Java se ejecutan en Eclipse Indigo en 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(); 
    } 
} 

Respuesta

4

Al cerrar la anidada PrintWriter, también cerrar la System.out flujo incrustado, lo que aparentemente evita que más escribe a ella (aunque lo haría esperar una excepción realmente en lugar de tragar la salida).

Así que todo el problema se puede reducir a:

public class Tester { 

    public static void main(String[] args) {   
     System.out.println("first"); 
     System.out.close(); 
     System.out.println("second");   
    } 
} 

Esto también no imprime más después de "primera", pero también no lanzar una excepción. Una sesión de depuración muy rápida muestra que hay una llamada a una función nativa de Sun, que es un poco más difícil de depurar.

actualización *

Este es el culpable: System.out es de tipo java.io.PrintStream y contiene la siguiente preciosa método:

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; 
    } 
} 

El método ensureOpen() de hecho se produce una excepción, pero se la traga aquí y se establece el indicador trouble (un anti-patrón bien conocido). Esto ignora silenciosamente escrituras adicionales en la secuencia cerrada.

1

De la documentación de close() Dice

Cierra el flujo y libera los recursos del sistema asociados con ella. Cerrar una secuencia previamente cerrada no tiene efecto

Así que supongo que está liberando el System.out y por lo tanto no se puede volver a utilizar. Además, agregué una línea System.out.println("Finished"); al final y no muestra nada si se ha llamado a un cierre en System.out en el código. Pruébalo.

Cuestiones relacionadas