PrintWriter.println: примеры (JAVA)

Подробный материал по PrintWriter.println
Раздел: Потоки ввода-вывода (Streams) символьные
PrintWriter.println(String x): void

Общее описание PrintWriter.println

Метод PrintWriter.println из пакета java.io предназначен для вывода текстового представления значения с последующим переходом на новую строку. Вызов эквивалентен последовательности записи представления аргумента и символа новой строки, но не выбрасывает контролируемых исключений IOException. Метод перегружен для разных типов данных и возвращает void.

Поддерживаемые перегрузки:

  • println() - вывод только разделителя строки.
  • println(boolean x), println(char x), println(int x), println(long x), println(float x), println(double x) - вывод примитивов.
  • println(char[] x) - вывод массива символов.
  • println(String x) - вывод строки; если аргумент == null, выводится текст "null".
  • println(Object x) - вызывает String.valueOf(x) и затем выводит результат.

Поведение и важные детали:

  • Метод возвращает void, ошибок типа IOException не бросает. При ошибках внутренне устанавливается флаг ошибки, который можно проверить методом checkError().
  • Формат конца строки зависит от платформы, используемой реализацией среды выполнения (обычно \n на Unix-подобных системах, \r\n на Windows-окружениях) или от реализаций внутреннего буфера.
  • При создании PrintWriter можно указать autoFlush. Если autoFlush равен true, то вызов методов println, printf или format приводит к автоматической фиксации буфера (flush).
  • Кодировка определяется тем Writer или OutputStream, который оборачивается. Многие конструкторы PrintWriter используют платформенную кодировку, поэтому для контроля кодировки рекомендуется применять OutputStreamWriter с явным Charset или использовать API Files.newBufferedWriter(..., Charset).
  • PrintWriter не гарантирует синхронизацию доступа для многопоточного использования; при необходимости требуется внешняя синхронизация.

Короткие примеры применения println

Примеры демонстрируют основные перегрузки и типичные сценарии вывода. В каждом примере показан код и ожидаемый результат.

1. Запись в StringWriter

import java.io.PrintWriter;
import java.io.StringWriter;

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println("Hello, World!");
pw.println(123);
pw.println((Object)null);
pw.flush();
String out = sw.toString();
System.out.print(out);
Hello, World!
123
null

2. Автофлаш и ByteArrayOutputStream

import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pwNoAuto = new PrintWriter(new OutputStreamWriter(baos));
pwNoAuto.print("no-auto");
// пока не flush, байты могут оставаться в буфере
pwNoAuto.flush();
System.out.println(new String(baos.toByteArray()));

baos.reset();
PrintWriter pwAuto = new PrintWriter(new OutputStreamWriter(baos), true);
pwAuto.println("with-auto");
System.out.println(new String(baos.toByteArray()));
no-auto
with-auto

3. Вывод примитива и массива символов

PrintWriter pw = new PrintWriter(System.out, true);
char[] chars = {'A','B','C'};
pw.println(chars);
pw.println(3.14);
// результат выводится в консоль напрямую
ABC
3.14

4. Поведение с null

PrintWriter pw = new PrintWriter(System.out, true);
String s = null;
pw.println(s);
null

Похожие инструменты в Java

Существуют близкие по назначению средства вывода в Java, отличающиеся семантикой, обработкой ошибок и возможностями форматирования:

  • PrintStream.println - вывод байтов; также имеет autoFlush-возможность при создании через конструктор. В отличие от PrintWriter, ориентирован на байтовые потоки, часто используется как System.out. Также не бросает IOException и использует внутренний флаг ошибок.
  • BufferedWriter.write + newLine() - более низкоуровневый способ записи, требует ручного вызова newLine() и flush(), бросает IOException, что удобно при строгой обработке ошибок.
  • Formatter/PrintWriter.printf - для форматированного вывода по шаблону; полезно при необходимости форматирования чисел и строк согласно локали.
  • java.util.logging.Logger или другие логгеры - для логирования с уровнями, ротацией, обработчиками; предпочтительны для приложений с требованиями к логам.

Выбор зависит от требований: для простого текстового вывода и игнорирования проверяемых ошибок часто подходит PrintWriter. При необходимости обработки ошибок по исключениям - предпочтительнее BufferedWriter или явная работа с IOException.

Аналоги в других языках

Короткий обзор аналогичных механизмов вывода в популярных языках и отличия от Java:

  • PHP: echo и print. Выводит строку сразу; нет встроенного автофлеша в таком же виде. Пример:
    <?
    echo "Hello" . PHP_EOL;
    ?>
    Hello
    
  • JavaScript (браузер): console.log(). Для логов в консоль; автоматически добавляет перевод строки в отладочной консоли.
    console.log('Hello');
    Hello
  • Node.js: console.log и process.stdout.write. process.stdout.write более низкоуровневый и не добавляет перевод строки автоматически.
    process.stdout.write('Hi\n');
    Hi
    
  • Python: print(). По умолчанию добавляет перевод строки; поддерживает параметр end и перенаправление в файл.
    print('Hello')
    Hello
    
  • C#: Console.WriteLine(). По семантике близок к Java println.
  • Go: fmt.Println(). Добавляет пробелы между аргументами и перевод строки в конце.
  • Kotlin: println(). В стандартной библиотеке вызывает вывод в System.out, семантика близка к Java.
  • Lua: print(). Добавляет табуляцию между аргументами и перевод строки.
  • SQL (PL/pgSQL): RAISE NOTICE для вывода сообщений на уровне СУБД. Не эквивалент линейному выводу в приложении, но служит для отладки.

Отличия от Java: в большинстве языков стандартный вывод немедленно отображается в консоли и может бросать исключения или ошибки по-другому. Java разделяет концепции байтового (PrintStream) и символьного (PrintWriter) вывода и допускает управление кодировкой через оборачивающие классы.

Типичные ошибки при использовании println

Частые ситуации, приводящие к неожиданному поведению:

  • Игнорирование ошибок ввода-вывода.

Поскольку PrintWriter не бросает IOException, ошибки могут быть незаметны. Пример с симуляцией ошибки:

import java.io.Writer;
import java.io.IOException;
import java.io.PrintWriter;

class BadWriter extends Writer {
    public void write(char[] cbuf, int off, int len) throws IOException {
        throw new IOException("simulated IO error");
    }
    public void flush() {}
    public void close() {}
}

PrintWriter pw = new PrintWriter(new BadWriter());
pw.println("test");
boolean err = pw.checkError();
System.out.println("error: " + err);
error: true

Вывод: проверка checkError() обязательна, если требуется надежная обработка ошибок.

  • Потеря данных из-за не вызова flush или close.

Если autoFlush = false, данные могут остаться в буфере до закрытия или явного flush. При записи в файл это приведет к неполной записи, если приложение завершится некорректно.

  • Неправильная кодировка.

Использование конструкторов без указания кодировки приводит к применению системной кодировки. Для переносимости рекомендуется явно указывать Charset через обёртки.

  • Вывод null.

Передача null в println(String) приводит к выводу текста "null", что может быть неожиданным при форматировании.

Изменения в реализации PrintWriter

API PrintWriter является устоявшимся и критических изменений в семантике println за последние релизы Java не происходило. Рекомендации эволюционируют в сторону явного указания кодировки (через OutputStreamWriter или Files.newBufferedWriter) и использования конструкций try-with-resources для гарантированного закрытия. Депрекаций или новых перегрузок println в последних версиях не отмечалось.

Расширенные и редкие сценарии использования

Подробные примеры показывают нетривиальные применения PrintWriter.println.

1. Запись CSV с контролем кодировки и try-with-resources

Пример java
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

Path p = Path.of("out.csv");
try (PrintWriter pw = new PrintWriter(Files.newBufferedWriter(p, StandardCharsets.UTF_8))) {
    pw.println("id,name,score");
    pw.println("1,Иван,85");
    pw.println("2,Мария,92");
}
// Файл out.csv содержит текст в UTF-8
(файл out.csv)
id,name,score
1,Иван,85
2,Мария,92

2. PrintWriter поверх сокета с autoFlush

Пример java
import java.net.Socket;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;

// клиентская часть: отправка запроса серверу
Socket s = new Socket("example.com", 12345);
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), java.nio.charset.StandardCharsets.UTF_8), true)) {
    pw.println("GET /status");
    // println с автофлешем сразу отправляет строку
}
(строка отправлена на сетевой сокет и сразу передана)

3. Обработка ошибок через checkError() после серии операций

Пример java
PrintWriter pw = new PrintWriter("out.txt");
pw.println("one");
pw.println("two");
if (pw.checkError()) {
    System.err.println("Произошла ошибка при записи");
}
pw.close();
(если ошибок нет, сообщений в stderr нет)

4. Форматированный вывод с автофлешем

Пример java
PrintWriter pw = new PrintWriter(System.out, true);
pw.printf("Name: %s, Score: %.1f\n", "Анна", 9.5);
// printf может триггерить автофлеш при autoFlush = true
Name: Анна, Score: 9.5

5. Сценарий: перехват исключений оборачивающим Writer и восстановление

Пример java
import java.io.Writer;
import java.io.IOException;
import java.io.PrintWriter;

class FaultyOnceWriter extends Writer {
    private boolean first = true;
    public void write(char[] cbuf, int off, int len) throws IOException {
        if (first) { first = false; throw new IOException("temporary"); }
        // далее ведёт себя нормально
    }
    public void flush() {}
    public void close() {}
}

PrintWriter pw = new PrintWriter(new FaultyOnceWriter());
pw.println("try1");
if (pw.checkError()) {
    // попытка восстановить заменой Writer
    pw = new PrintWriter(new java.io.StringWriter());
    pw.println("recovered");
    pw.flush();
}
// В результате будет записано восстановленное сообщение
(внутренние проверки и восстановление произведены)

Эти примеры показывают комбинации контроля кодировки, автофлеша, сетевых сценариев и стратегии обработки скрытых ошибок.

джава PrintWriter.println function comments

En
PrintWriter.println Prints a line of text and then terminates the line