Несколько дней назад я понял, что PrintWriter (а также PrintStream) никогда не генерировать исключение IOException при записи, прошивке или закрытии.
Вместо этого он устанавливает внутренний флаг (trouble=true) при возникновении ошибки.
Невозможно получить точное исключение, но только если было какое-то исключение (checkError ()).
У меня вопрос: зачем нужно такое поведение? Разве это не плохой дизайн API?




Я действительно не знаю истории, но я думаю, что это было сделано для того, чтобы упростить 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 редко используется в производственном коде, а его использование в основных библиотеках ограничивается ведением журнала, при котором сбои можно безопасно игнорировать.
Они по-прежнему могут генерировать исключение времени выполнения вместо IOException, а не устанавливать внутренний флаг.
Sun / Oracle следовало добавить две функции, похожие на запись: одна генерирует исключение IOException, а другая ничего не генерирует.
Это не ошибка дизайна. Это правильный дизайн, предназначенный для использования в ситуации, когда вы пишете вывод и хотите, чтобы ошибки игнорировались.
В качестве типичного варианта использования уже упоминались System.out и System.err, но причина не в расслабленное обращение для удобство или плавные переходы C / C++. Это желаемое решение такой ситуации:
В этой ситуации, в зависимости от реализации системы, может случиться так, что System.out или System.err выйдет из строя после закрытия консоли, но вы не хотите, чтобы это привело к сбою вашего приложения. Требуется, чтобы приложение продолжало работать в фоновом режиме, а вывод должен быть очищен. Вот что делает PrintWriter.
Если вас беспокоят ошибки во время вывода, используйте FileWriter или OutputStreamWriter.
Если вам нужны некоторые из методов, доступных в PrintWriter и недоступных в FileWriter, создайте свой собственный TextWriter, расширяющий FileWriter или OutputStreamWriter.
Я просто искал это. Я тоже нашел это действительно странным. Одно дело - скрыть исключение, а вот отбросить его вообще? Что, если я действительно хочу узнать содержимое исключения? Я ожидал получить метод getError (), но ... это действительно странное дизайнерское решение.