почему локальный PrintWriter мешает другому локальному PrintWriter? - PullRequest
5 голосов
/ 07 августа 2011

В этой программе третья строка никогда не печатается. Зачем?

(Эта Java-программа была запущена в Eclipse Indigo в 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();
    }
}

Ответы [ 2 ]

4 голосов
/ 07 августа 2011

Закрывая вложенный PrintWriter, вы также закрываете встроенный поток System.out, который, по-видимому, предотвращает дальнейшие записи в него (хотя я бы ожидал, что на самом деле вместо глотания вывода).

Так чтовся проблема может быть уменьшена до:

public class Tester {

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

Это тоже больше не печатается после "first" , но также не вызывает исключения.Очень быстрый сеанс отладки показывает, что есть вызов собственной функции Sun, в которую немного сложнее отладить.

Обновление *

Это виновник: System.out относится к типу java.io.PrintStream и содержит следующий прекрасный метод:

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

Метод ensureOpen() действительно вызывает исключение, но здесь он проглатывается и troubleфлаг установлен (хорошо известный анти-шаблон).Таким образом, это молча игнорирует дальнейшие записи в закрытый поток.

1 голос
/ 07 августа 2011

Из документации close () написано

Закрывает поток и освобождает любые связанные с ним системные ресурсы.Закрытие ранее закрытого потока не имеет никакого эффекта

Так что я предполагаю, что он освобождает System.out и, следовательно, не может быть использован снова.Кроме того, я добавил строку System.out.println("Finished"); в конце, и она ничего не выводит, если в коде было вызвано закрытие на System.out.Попробуйте.

...