PrintWriter и PrintStream никогда не генерируют исключения IOExceptions

Несколько дней назад я понял, что PrintWriter (а также PrintStream) никогда не генерировать исключение IOException при записи, прошивке или закрытии.

Вместо этого он устанавливает внутренний флаг (trouble=true) при возникновении ошибки. Невозможно получить точное исключение, но только если было какое-то исключение (checkError ()).

У меня вопрос: зачем нужно такое поведение? Разве это не плохой дизайн API?

Я просто искал это. Я тоже нашел это действительно странным. Одно дело - скрыть исключение, а вот отбросить его вообще? Что, если я действительно хочу узнать содержимое исключения? Я ожидал получить метод getError (), но ... это действительно странное дизайнерское решение.

aberrant80 28.01.2010 15:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
23
1
5 194
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Я действительно не знаю истории, но я думаю, что это было сделано для того, чтобы упростить Java для начинающих программистов, которым дизайнеры хотели иметь возможность использовать простые методы печати stdio без необходимости знать, что такое исключения. Так что в этом отношении это хороший дизайн (хотя я с вами в чем-то согласен).

Возможно, что дизайн был сделан кем-то из фона C, где ошибки stdio обрабатываются аналогичным образом. Поскольку я привык к этой парадигме, я бы не назвал ее плохой, но согласен, что она непоследовательна.

Я также согласен с комментарием о попытке упростить использование PrintWriter. Классы ввода-вывода в Java сбивают с толку (по крайней мере, для всех, кого я знаю), и, возможно, кто-то просто пытался немного облегчить жизнь.

Ответ принят как подходящий

Я думаю, что, поскольку System.out и System.err являются экземплярами PrintStream, была обеспечена более мягкая обработка ошибок. Вероятно, это было, как упоминалось в других плакатах, для того, чтобы сгладить путь для тех, кто переходил с C / C++ примерно в 1995 году. Когда был добавлен API чтения / записи, был создан PrintWriter для параллельного использования существующего PrintStream.

Одно приложение, в котором такое поведение крайне желательно, - это ведение журнала. Ведение журнала является вспомогательным для более крупного приложения. Обычно, если ведение журнала не удается, не нужно, чтобы все приложение терпело неудачу. Таким образом, для System.err имеет смысл, по крайней мере, игнорировать исключения.

Интересно, если из-за того, что IOExceptions проверены, вам потребуется разместить блок try catch вокруг каждого System.out. вызов.

update: Или бросает в подпись вашего метода.

Это очень быстро надоедало.

Разумеется, проверенное исключение не требует строго блока try-catch. PrintStream редко используется в производственном коде, а его использование в основных библиотеках ограничивается ведением журнала, при котором сбои можно безопасно игнорировать.

erickson 18.11.2008 06:12

Они по-прежнему могут генерировать исключение времени выполнения вместо IOException, а не устанавливать внутренний флаг.

Gonen I 04.09.2016 01:16

Sun / Oracle следовало добавить две функции, похожие на запись: одна генерирует исключение IOException, а другая ничего не генерирует.

Это не ошибка дизайна. Это правильный дизайн, предназначенный для использования в ситуации, когда вы пишете вывод и хотите, чтобы ошибки игнорировались.

В качестве типичного варианта использования уже упоминались System.out и System.err, но причина не в расслабленное обращение для удобство или плавные переходы C / C++. Это желаемое решение такой ситуации:

  • вы запускаете приложение в консоли
  • он производит вывод в std out / err
  • вы закрываете консоль, но хотите, чтобы приложение продолжало работать в фоновом режиме

В этой ситуации, в зависимости от реализации системы, может случиться так, что System.out или System.err выйдет из строя после закрытия консоли, но вы не хотите, чтобы это привело к сбою вашего приложения. Требуется, чтобы приложение продолжало работать в фоновом режиме, а вывод должен быть очищен. Вот что делает PrintWriter.

Если вас беспокоят ошибки во время вывода, используйте FileWriter или OutputStreamWriter. Если вам нужны некоторые из методов, доступных в PrintWriter и недоступных в FileWriter, создайте свой собственный TextWriter, расширяющий FileWriter или OutputStreamWriter.

Другие вопросы по теме